2013-10-09 2 views
0

Я создаю библиотеку комплексных чисел/функций CUDA/C++. В частности, я определил свои собственные реализации сложных типов int2_, float2_ и double2_ в ComplexTypes.cuh и ComplexTypes.cu файлов, и я иметь следующую структуру файла:Неопределенная ссылка на типы типов

Result_Types.cuh - типа файла черты - Определяет result_type_promotion,

/*************/ 
/* PROMOTION */ 
/*************/ 
template <typename, typename> struct result_type_promotion; 
.... 
template<> struct result_type_promotion< int2_, float2_ > { typedef float2_ strongest; }; 
.... 

/*************/ 
/* FUNCTIONS */ 
/*************/ 

template <typename> struct result_type_root_functions; 
.... 

Operator_Overloads.cuh

template<typename T0, typename T1> __host__ __device__ typename result_type_promotion<T0, T1>::strongest operator+(T0, T1); 
.... 

Operator_Overloads.cu - Перегрузки общих операций между комплексными числами

#include "ComplexTypes.cuh"          
#include "Result_Types.cuh" 
#include "Operator_Overloads.cuh" 
.... 
__host__ __device__ result_type_promotion<int2_,float2_>::strongest   add(const int2_ a, const float2_ b) { result_type_promotion<int2_,float2_>::strongest   c; c.c.x = a.c.x+b.c.x; c.c.y = a.c.y+b.c.y; return c; } 
.... 
__host__ __device__ result_type_promotion<int2_,float2_>::strongest operator+(const int2_ a,const float2_ b) { return add(a,b); } 

Function_Overloads.cuh

template<typename T0> typename result_type_root_functions<T0>::root_functions     Asinh(T0); 

Function_Overloads.cu - Перегрузки функций на комплексных чисел

#include "ComplexTypes.cuh"          
#include "Result_Types.cuh" 
#include "Operator_Overloads.cuh" 

__host__ __device__ result_type_root_functions<int>::root_functions   Asinh(const int a)    { return asinh((float)a); } 
.... 

Вышеупомянутые файлы, за исключением файла типов признаков, который рассматривается как файл включения, скомпилированы в командной строке с использованием nvcc и cl, чтобы сформировать файл .lib.

К сожалению, когда я составляю основную функцию, которая включает в себя

#include "ComplexTypes.cuh" 
#include "Result_Types.cuh" 
#include "Operator_Overloads.cuh" 
#include "Function_Overloads.cuh" 

У меня есть ошибки сцепления типа

Error 247 error : Undefined reference to '_ZplIN2BB5int2_ENS0_7float2_EEN21result_type_promotionIT_T0_E9strongestES4_S5_' in '...Test.lib' 

Примечание Пожалуйста, что:

  1. Только сложные типы int2_, float2_ и double2_ находятся в BB, но я добавляю using namespace BB; во все файлы определений;
  2. Проблема возникает, когда я использую + в файле Function_Overloads.cu; если я не использую +, тогда проблем не возникает;
  3. I (удивительно) может использовать + в функции main без получения каких-либо ошибок связи.

Любая идея для решения этой проблемы?

Спасибо.

EDIT

После предложения billz, я решил эту проблему, добавив явные экземпляры в файле Function_Overloads.cu, как

__host__ __device__ result_type_promotion<int,int2_>::strongest operator+(const int a,const int2_ b); 
.... 
+1

где определяется 'operator +'? – billz

+0

@billz В файле 'Operator_Overloads.cu' см. Выше. – JackOLantern

ответ

1

_ZplIN2BB5int2_ENS0_7float2_EEN21result_type_promotionIT_T0_E9strongestES4_S5_

декодируется c++filt становится:

result_type_promotion<BB::int2_, BB::float2_>::strongest operator+<BB::int2_, BB::float2_>(BB::int2_, BB::float2_) 

Что означает, что ваш компилятор не может найти определение функции, вы должны реализовать его в заголовочном файле.

+0

Большое спасибо за указание на это, а также на использование 'C++ filt'. Мне не очень понятно, почему после создания статической библиотеки я могу использовать оператор '+' в функции 'main', но у меня нет видимости такой перегрузки внутри функции, определенной в' Function_Overloads.cu'. Не могли бы вы предложить любой тест, который я могу сделать для решения этой проблемы (при условии, что эта проблема _has_ решение :-))? – JackOLantern

+0

Эта ссылка может помочь: http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – billz

+0

Я добавил явные экземпляры (не реализации) в ' Function_Overloads.cu', и это решило проблему. Следуя вашей ссылке, я понимаю, что в моей первоначальной версии в компиляционной единице 'Function_Overloads.cu' не было никаких экземпляров, которые впоследствии были связаны, и я также понимаю, почему теперь явные экземпляры решают проблему. Однако я не понимаю, почему в функции «main» все работает без явных инстанций. – JackOLantern

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