2012-05-01 6 views
2

私はTensorのテンプレート表現を使用して外側の製品を実装しています。このテンソル外積で無限のテンプレート再帰が発生する原因は何ですか?

テンソルの基本的なプロトタイプは次のようになります。簡単なベクトルに分解するためにTensor<1>のための専門で

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

。注文NのテンソルAおよび順序MのテンソルBの外積は、単にBテンソルとAの各要素の外積である

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; 
} 

:私のOuter関数は以下のように定義されます。テンソルの次数がNであり、テンソルが1の任意のテンソルの外積も同様に定義される。

ベースケースは、単に2つの次数1テンソル(ベクトル)の外積です。 I上で定義されているように、除き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,y、およびzのデータメンバーをデフォルトで構築しようとするため、Tensor<1>の専門化はデフォルト構成可能である必要があります。
  3. template<int N> Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs)で対称にするには、過負荷が必要です。また、lhsにはdoubleのオーバーロードを追加する必要があります。
  4. Tensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs)オーバーロード–からtemplate<>を削除してください。ここにはオーバーロードがあります。
+0

を私はあなたがこの投稿を権利としてそれを考え出した - 私は 'テンソル<1>'外積後に定義の基本ケースの定義を持っていたからです。 –

+0

謝罪は、私はあなたが変更を加え知りませんでした。 –

関連する問題