문제

수업이 있습니다

template <unsigned int N>
class StaticVector {
// stuff
};

이 클래스 A에서 선언하고 정의 할 수있는 방법 정적 팩토리 메소드 정적 벡터 <3> 개체, STH 좋아요

StaticVector<3> create3dVec(double x1, double x2, double x2);

?

도움이 되었습니까?

해결책

"이 수업에서 어떻게 선언하고 정의 할 수 있습니까?"

어떤 수업에서? 클래스가 아닌 클래스 템플릿을 정의했습니다. 클래스 템플릿 자체의 정적 함수를 호출 할 수 없으므로 실제 클래스의 일부인 정적 기능의 특정 버전을 호출해야합니다.

따라서 템플릿 (따라서 모든 인스턴스화)이 staticVector <3>를 반환하는 함수를 갖기를 원하십니까, 아니면 해당 템플릿의 특정 인스턴스화가 staticVector <3>를 반환하는 기능을 갖기를 원하십니까?

전자 :


  template <unsigned int N>
  struct SV {
    int contents[N];
    static SV<3> get3dVec(int x, int y, int z) {
      SV<3> v;
      v.contents[0] = x;
      v.contents[1] = y;
      v.contents[2] = z;
      return v;
    }
  };

  int main() {
    SV<3> v = SV<1>::get3dVec(1,2,3);
  }

나를 위해 일합니다.

후자 (get3dvec가 sv <3>의 회원이되기를 원한다면 모든 SV가 아닙니다.u003Cwhatever> ), 그런 다음 템플릿 전문화를 원합니다 :


  template <unsigned int N>
  struct SV {
    int contents[N];
  };

  template<>
  struct SV<3> {
    int contents[3]; // must be re-declared in the specialization
    static SV<3> get3dVec(int x, int y, int z) {
      SV<3> v;
      v.contents[0] = x;
      v.contents[1] = y;
      v.contents[2] = z;
      return v;
    }
  };

  int main() {
    SV<3> v = SV<1>::get3dVec(1,2,3); // compile error
    SV<3> v = SV<3>::get3dVec(1,2,3); // OK
  }

기본적으로 관련없는 템플릿 매개 변수를 생략하여 호출 코드를 더 멋지게 보이게하는 것 외에 다른 이유가 없다면, 나는 일반적으로 무료 함수 (재사용을 위해 쓰는 경우 네임 스페이스에서)가 더 의미가있는 iRaimbilanja와 동의합니다. 예시.

C ++ 템플릿은 Java에서와 마찬가지로 C ++에서 정적 기능이 필요하지 않다는 것을 의미합니다. 클래스 막대를 위해 한 가지를 수행하는 "Foo"기능을 원한다면 클래스 BAZ를 위해 다른 일을하려면 기능으로 선언 할 수 있습니다. 각 클래스에서 정적 함수로 만드는 대신 막대 또는 baz (및 함수 매개 변수에서 추론 될 수 있거나 추론되지 않을 수있는 템플릿 매개 변수가있는 템플릿. 그러나 정적 함수가되기를 원한다면 템플릿 이름이 아니라 특정 클래스를 사용하여 호출해야합니다.

다른 팁

같은 것 :

template< unsigned int SIZE >
StaticVector< SIZE > createVec( const std::tr1::array< double, SIZE >& values )
{ 
     StaticVector< SIZE > vector;
     for( int i = 0; i < values.size(); ++i ) // here assuming that StaticVector have [] operator to access values on write
     {
         vector[i] = values[i];
     }

     return vector;
}

... 또는 변형은 확실히 작동합니다. (테스트하지 않았어)

사용법은 다음과 같습니다.

std::tr1::array< double, 3 > vectorValues = { 10.0, 10.0, 42.0 };

StaticVector<3> vector1 = createVector( vectorValues ); // if the compiler can guess the size from the array information
StaticVector<3> vector2 = createVector<3>( vectorValues ); // if you have to specify the size

대안은 std :: tr1 :: 배열을 기본 배열로 대체하는 것이지만, 자신의 위험에 따라 원시 어레이를 사용하는 것입니다 :)

첫째, 나는 당신이 원래 돌아 오는 것을 의미한다고 믿습니다

StaticVector<N>

n == 3의 전문화 대신. 그래서 당신이하고 싶은 것은 다음과 같이 쓰는 것입니다.

template <unsigned int N>
class StaticVector {
public:
    // because of the injected class-name, we can refer to us using
    // StaticVector . That is, we don't need to name all template
    // parameters like StaticVector<N>.
    static StaticVector create3dVec(double x1, double x2, double x2) {
        // create a new, empty, StaticVector
        return StaticVector();
    }

};

항상 3DVECTOR를 반환하려면 N == 3으로 제한하고 싶을 것입니다. 예를 들어 StaticVector<4>::create3dVec 작동하지 않습니다. 설명 된 기술을 사용하여 그렇게 할 수 있습니다 여기.

당신이 같은 기능을 원한다면 createVec 어떤 크기로든 작동하면 매개 변수를 배열로 바꾸고 싶을 것입니다. 당신은 다른 방법으로 할 수 있지만, 그것은 고급이며 boost :: preprocessor와 함께 적용되는 매크로 트릭이 필요합니다. 그만한 가치가 없습니다. 다음 C ++ 버전이 제공합니다 변수 템플릿 이 목적을 위해. 어쨌든 다음과 같은 것을 사용하는 것을 고려하십시오.

나는 그것이 불필요하게 여기서 불필요하게 복잡하게 될 것이라고 생각합니다. 빠른 해결책은 Boost :: Fusion :: Vector를 사용하여 위의 버전 대신 클래스 템플릿에 넣는 것입니다.

static StaticVector createVec(double (&values)[N]) {
    // create a new, empty, StaticVector, initializing it
    // with the given array of N values.
    return StaticVector();
}

당신은 그것을 함께 사용할 수 있습니다

double values[3] = {1, 2, 3};
StaticVector<3> v = StaticVector<3>::createVec(values);

참조로 배열을 허용합니다. 포인터를 줄 수는 없습니다. 그것은 매개 변수의 사용과 일치하기 때문입니다. 당신은 다른 방식에 대해서도 더 이상 인수를 제공 할 수 없었습니다. 또한 다음과 같은 경우로부터 귀하를 보호 할 것입니다.

// oops, values is a null pointer!
StaticVector<3> v = StaticVector<3>::createVec(values);

배열은 결코 널 포인터가 될 수 없습니다. 물론 원하는 경우 항상 배열 매개 변수를 포인터로 변경할 수 있습니다. 그것은 단지 내 개인적인 취향 일 것입니다 :)

@litb

3 요소 벡터를 반환하고 싶었습니다. 그 이유는 이러한 벡터가 기하학적 실체로 여겨 져야하므로 N이 너무 높아질 필요가 없기 때문입니다 (나는 문자열 물리학자가 아니므로 11 차원 공간에서 작동하지 않습니다). 복제 코드를 피하기 위해 템플릿을 만들고 싶지만 1-, 2 차원 및 3 차원 벡터를 별도의 유형으로 유지하려고했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top