2013-09-27 2 views
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+ перегрузкам между всеми возможными комбинациями int, float, double, int2_, float2_ и double2_?

Обратите внимание, что я не могу «навести порядок» на реализацию, поскольку различные комбинации добавлений числа будут иметь разные реализации.

спасибо.

РЕДАКТИРОВАТЬ - ПРЕДВАРИТЕЛЬНЫЙ раствора после ПРЕДЛОЖЕНИЙ Дитмара КУЭЛ

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

BB является namespace, в котором определены сложные типах.

+0

Я бы полностью пропустил шаблоны и просто выполнил кучу перегрузок. – aschepler

+0

@aschepler Почему вы рекомендуете это? – JackOLantern

ответ

1

Вы написали явное инстанцирование неопределенного шаблона. Вы, вероятно, имел в виду, чтобы написать полную специализацию:

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

Я думаю, однако, что все, что вызов этих специализаций на самом деле нужно было бы видеть декларацию специализаций. Даже если это определение в порядке, вам не будет с ним много удовольствия: тип возвращаемого значения не может быть выведен, т. Е. Вам нужно явно указывать тип возврата при вызове этого оператора. Я сомневаюсь, что это вы намерены делать. Способ исправления второй проблемы - это, вероятно, какой-то класс признаков, который определяет тип результата на основе типов аргументов. Чтобы решить первую проблему, я применил общий шаблон делегирования другой функции и явным образом создавал ее в блоке перевода.

Работа с типом возвращаемого значения может выглядеть примерно так:

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 
+0

Прежде всего, большое спасибо за ваши предложения. Ваш код напрямую не компилируется, но предоставил мне общую идею. Я немного поиграл и нашел решение, которое правильно компилируется, см. Мой отредактированный пост. К сожалению, при использовании в моем проекте компилятор говорит, что никакой оператор «+» не соответствует этим операндам ... – JackOLantern

+0

Я думаю, у меня есть рабочее решение. Он компилирует и дает правильный результат. Я добавил его ко второму отредактированному сообщению. Огромное спасибо. – JackOLantern

Смежные вопросы