1

我已经float2_通过以下方式定义了我自己的复杂类

class float2_ {

    public:
        float2 c;

        // Member functions
}

float2是一个 CUDA struct,基本上是几个实部和虚部。同样,我已经定义了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_);

编辑 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

You wrote an explicit instantiation of an undefined template. You probably meant to write a full specialization:

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

I think, however, that anything calling these specializations would actually need to see the declaration of the specializations. Even if this definition is OK, you won't have much fun with it: the return type cannot be deduced, i.e., you need to explicitly specify the return type when calling this operator. I doubt that is what you intend to do. The way to fix the second problem is probably some sort of a traits class which determines the result type based on the argument types. To address the first problem I have implemented the general template delegating to another function and explicitly instantiating it in a translation unit.

Dealing with the return type could look something like this:

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

... and the implementation in a translation unit could look something like this:

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 回答