1

float2_次の方法で独自の複雑なクラスを定義しました

class float2_ {

    public:
        float2 c;

        // Member functions
}

float2は CUDAstructであり、基本的に実部と虚部のカップルです。同様に、クラスを定義int2_しました。double2_

operator+ここで、実数/複素数と複素数/複素数の可能なすべての組み合わせをオーバーロードしたいと思います。さらに、ヘッダー ファイルでは、これらすべての可能性を明示的に宣言することを避けるために、テンプレートを使用したいと考えています。

それで、私が試したのは次のとおりです。

// .cuh file
template<class A, class B, class C> C operator+(const A,const B);

// .cu file
template float2_::float2_ operator+(const int2_::int2_,const float2_::float2_) 
{ // implementation };
....

しかし、これは私に次のエラーメッセージを返します:

Operator_Overloads.cu(65): error: this declaration has no storage class or type specifier

Operator_Overloads.cu(65): error: invalid explicit instantiation declaration

私の質問は、* operator+、、、、、および?intfloatdoubleint2_float2_double2_

数の加算の組み合わせが異なると実装が異なるため、実装を「テンプレート化」することはできないことに注意してください。

どうもありがとうございました。

編集 - DIETMAR KUEHL の提案に基づく暫定的な解決策

 // Include file
 template<typename T0, typename T1, typename T2> T2 operator+(T0, T1);

 // --- Translational unit

 // --- Auxiliary function add --- complex/complex
 BB::float2_ add(const BB::int2_ a, const BB::float2_ b) { BB::float2_ c; c.c.x = (float)a.c.x + b.c.x; c.c.y = (float)a.c.y + b.c.y; return c; };

 // --- Template definition of operator+
 template <typename T0, typename T1, typename T2> T2 operator+(T0 o0, T1 o1) { return add(o0, o1); }

 // --- Instantiation of operator+
 template BB::float2_ operator+<BB::int2_, BB::float2_>(BB::int2_, BB::float2_);

EDIT 2 - ワーキングソリューション

 // --- Include file
 template <typename, typename> struct result_type;
 template <>
 struct result_type<BB::int2_, BB::float2_> {
      typedef BB::float2_ type;
 };

 template<typename T0, typename T1> typename result_type<T0, T1>::type operator+(T0, T1);

 // --- Translational unit
 BB::float2_ add(const BB::int2_ a, const BB::float2_ b) { BB::float2_ c; c.c.x = (float)a.c.x + b.c.x; c.c.y = (float)a.c.y + b.c.y; return c; };
 BB::float2_ operator+(BB::int2_ a, BB::float2_ b) { return add(a, b); };

BBnamespace、複合型が定義されている場所です。

4

1 に答える 1

1

未定義のテンプレートの明示的なインスタンス化を記述しました。あなたはおそらく完全な専門化を書くつもりでした:

template<>
float2_::float2_ operator+<int2_::int2_, float2_::float2_, float2_::float2_>(
    const int2_::int2_,const float2_::float2_) 
{
    // ...
}

ただし、これらの特殊化を呼び出すものは、実際には特殊化の宣言を確認する必要があると思います。この定義に問題がなかったとしても、あまり楽しくありません。戻り値の型を推測することはできません。つまり、この演算子を呼び出すときに戻り値の型を明示的に指定する必要があります。私はそれがあなたが意図していることだとは思えません。2 番目の問題を修正する方法は、おそらく、引数の型に基づいて結果の型を決定するある種の特性クラスです。最初の問題に対処するために、別の関数に委譲し、翻訳単位で明示的にインスタンス化する一般的なテンプレートを実装しました。

戻り値の型を処理すると、次のようになります。

template <typename, typename> struct result_type;
template <typename T0, typename T1>
struct result_type<int2_::int2_, float2_::float2_> {
    typedef float2_::float2_ type;
};
// other combinations

template <typename T0, typename T1>
typedef typename result_type<T0, T1>::type
operator+(T0, T1);

...そして、翻訳単位での実装は次のようになります。

float2_::float2_ add(int2_::int2_ o0, float2_::float2_ o1) {
    ...
}
// more overload of add()

template <typename T0, typename T1>
typedef typename result_type<T0, T1>::type
operator+(T0 o0, T1 o1) {
    return add(o0, o1);
}
template float2_::float2_ operator+<int2_::int2_, float2_::float2_>(
    int2_::int2_, float2_::float2_);
// more explicit instantiations
于 2013-09-27T16:06:30.410 に答える