2012-05-01 2 views
2

저는 Tensor의 템플릿 표현을 사용하여 바깥 쪽 제품을 구현하고 있습니다. Tensor<1> 간단한 벡터에 분해 할 수있는 전문성과 함께이 텐서 외부 생성물에서 무한 템플릿 재귀가 발생하는 이유는 무엇입니까?

template <int N> 
struct Tensor 
{ 
    Tensor<N - 1> x; 
    Tensor<N - 1> y; 
    Tensor<N - 1> z; 
}; 

:

텐서의 기본 프로토 타입처럼 보인다. 순서 N

template <int N, int M> 
Tensor<N + M> Outer(const Tensor<N> &lhs, const Tensor<M> &rhs) 
{ 
    Tensor<N + M> result; 

    result.x = Outer(lhs.x, rhs); 
    result.y = Outer(lhs.y, rhs); 
    result.z = Outer(lhs.z, rhs); 

    return result; 
} 

template <int N> 
Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs) 
{ 
    Tensor<N + 1> result; 

    result.x = Outer(lhs.x, rhs); 
    result.y = Outer(lhs.y, rhs); 
    result.z = Outer(lhs.z, rhs); 

    return result; 
} 

template <> 
Tensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs) 
{ 
    Tensor<2> result; 

    result.x.x = lhs.x * rhs.x; 
    result.x.y = lhs.x * rhs.y; 
    result.x.z = lhs.x * rhs.z; 

    // and so on 

    return result; 
} 

텐서 A의 외적을 순서 M의 텐서 B 단순히 B 텐서와 A의 각 요소의 외적이다 : 내 Outer 함수로서 정의된다. 텐서가 N이고, 텐서가 1 인 임의의 텐서의 외부 생성물도 유사하게 정의된다.

기본 케이스는 단지 두 개의 주문 1 텐서 (벡터)의 외적입니다. 를 제외하고, 내가 MSVC에 C1202 오류를 받고 있어요 위의 정의 :

오류 C1202 : 순환 형거나 너무 복잡한 함수 종속 컨텍스트

내가 외부 제품의 내 정의에 잘못된 무슨 짓을

?

+0

나를 위해 VS11 베타에서 잘 작동합니다. 어떤 번호를 사용하고 있습니까? 당신이 그것을 전문적으로 확신합니까? –

+0

VC10 SP1과 [잘 작동합니다] (http://ideone.com/LcKdP). [SSCCE] (http://sscce.org/)를 게시하십시오. – ildjarn

+0

@ildjarn : http://pastebin.com/rTU1c5BC이 최소 예제는 VS 2010 Ultimate SP1에서 C1202 오류를 발생시킵니다. –

답변

3

이 나를 위해 깨끗하게 빌드 :

template<int N> 
struct Tensor 
{ 
    Tensor<N - 1> x; 
    Tensor<N - 1> y; 
    Tensor<N - 1> z; 

    Tensor() { } 

    Tensor(const Tensor<N-1>& X, const Tensor<N-1>& Y, const Tensor<N-1>& Z) 
     : x(X), y(Y), z(Z) 
    { } 
}; 

template<> 
struct Tensor<1> 
{ 
    double x; 
    double y; 
    double z; 

    Tensor() : x(), y(), z() { } 
    Tensor(double x, double y, double z) : x(x), y(y), z(z) 
    { } 
}; 

template<int N, int M> 
Tensor<N + M> Outer(const Tensor<N>& lhs, const Tensor<M>& rhs) 
{ 
    Tensor<N + M> result; 

    result.x = Outer(lhs.x, rhs); 
    result.y = Outer(lhs.y, rhs); 
    result.z = Outer(lhs.z, rhs); 

    return result; 
} 

template<int N> 
Tensor<N + 1> Outer(const Tensor<N>& lhs, const Tensor<1>& rhs) 
{ 
    Tensor<N + 1> result; 

    result.x = Outer(lhs.x, rhs); 
    result.y = Outer(lhs.y, rhs); 
    result.z = Outer(lhs.z, rhs); 

    return result; 
} 

template<int N> 
Tensor<N + 1> Outer(const Tensor<1>& lhs, const Tensor<N>& rhs) 
{ 
    return Outer(rhs, lhs); 
} 

Tensor<2> Outer(const Tensor<1>& lhs, const Tensor<1>& rhs) 
{ 
    Tensor<2> result; 

    result.x.x = lhs.x * rhs.x; 
    result.x.y = lhs.x * rhs.y; 
    result.x.z = lhs.x * rhs.z; 
    result.y.x = lhs.y * rhs.x; 
    result.y.y = lhs.y * rhs.y; 
    result.y.z = lhs.y * rhs.z; 
    result.z.x = lhs.z * rhs.x; 
    result.z.y = lhs.z * rhs.y; 
    result.z.z = lhs.z * rhs.z; 

    return result; 
} 

int main() 
{ 
    Tensor<4> a; 
    Tensor<4> b; 
    Outer(a, b); 
} 

주목할만한 변경 사항은 다음과 같습니다

  1. Tensor<1> 전문화가 Outer 과부하의 전에 정의 될 필요가있다.
  2. Tensor<2>x, yz 데이터 멤버를 기본 생성하려고하므로 Tensor<1> 전문화가 기본 구성 가능해야합니다.
  3. template<int N> Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs)으로 대칭을 위해 과부하가 필요하거나 lhsdouble의 과부하를 추가해야합니다.
  4. Tensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs) 오버로드 –에서 template<>을 제거하십시오. 여기서는 오버플로입니다.
+0

당신이 이것을 게시 한대로 바로 알아 냈어 - 그것은'Tensor <1>'의 기본 케이스 정의가 외부 제품 후에 정의 되었기 때문입니다. –

+0

사과, 당신이 수정 한 것을 몰랐습니다. –

관련 문제