2013-12-04 3 views
4

Я хотел бы определить явную специализацию функции шаблона в файле cpp. Это возможно? Чтобы быть более конкретными, у меня есть следующий код, который компилируется без ошибок:Специализация функций члена шаблона класса без шаблона

//class.h 
class myclass 
{ 
public: 
    /* Constructor */ 
    myclass(); 
    /* Trigger fcn */ 
    template<typename T> T Trigger(T rn); 

private: 
    /* Specializations of the templated Trigger(...) function */ 
    template<> int Trigger<int>(int rn) 
    { 
     int_do(rn); 
    } 
    template<> double Trigger<double>(double rn) 
    { 
     double_do(rn); 
    } 
} 

Однако я имея определения в файле заголовок выглядит странно для меня, так что я хотел бы отделить определение от деклараций, что-то вроде этого:

//class.h 
class myclass 
{ 
public: 
    /* Constructor */ 
    myclass(); 
    /* Trigger fcn */ 
    template<typename T> T Trigger(T rn); 

private: 
    /* Specializations of the templated Trigger(...) function */ 
    template<> int Trigger<int>(int rn); 
    template<> double Trigger<double>(double rn); 
} 

и:

//class.cpp 
/* Specializations of the templated Trigger(...) function */ 
template<> int myclass::Trigger<int>(int rn) 
{ 
    int_do(rn); 
} 
template<> double myclass::Trigger<double>(double rn) 
{ 
    double_do(rn); 
} 

есть ли способ для этого?

+3

Это выглядит странно, не является достаточно хорошей причиной ИМО. Нет никакого способа сделать это, что не связано с каким-либо компромиссом, поэтому я бы просто привык к этому. – john

+2

Ваше определение шаблона должно оставаться в файле заголовка, но вы можете объявить функции, как у вас, вне определения класса {} (только в файле .h) – benjymous

+0

Возможный дубликат [Как объявить шаблон функция за пределами декларации класса] (http://stackoverflow.com/questions/1047663/how-do-i-declare-template-function-outside-the-class-declaration) – benjymous

ответ

8

Ваша единственная ошибка заключается в объявлении специализаций внутри класса. Объявить их в заголовке, но вне класса:

class myclass 
{ 
public: 
    myclass(); 
    template<typename T> T Trigger(T rn); 
}; 

/* Specializations of the templated Trigger(...) function */ 
template<> int myclass::Trigger<int>(int rn); 
template<> double myclass::Trigger<double>(double rn); 

, а затем вы можете определить их в исходном файле, точно так, как вы сделали.

Обратите внимание, что ваш первый фрагмент не компилируется (если ваш компилятор не имеет нестандартного расширения), так как специализации не могут быть объявлены внутри класса.

+0

Спасибо, Майк, теперь он компилируется. BTW, мой предыдущий код компилировался с VisualStudio 9.0, я не знаю, использует ли он нестандартное расширение или нет. – Iban

+0

Он отлично работает в компиляторе Microsoft. – marsh

+0

отлично, спасибо большое! – Kowshik

1

В дополнение к ранее ответ о позиционировании специализации:

Вы можете определить шаблон функции в файле .cpp. Это также означает, что они могут быть созданы только внутри этого объекта/файла трансляции. В вашем случае частичная специализация объявляется в .h, а другие единицы компиляции ожидают их существования.

Например, в файле tmp.h:

#include <iostream> 
class T { 
public: 
    template <typename T> void foo(const T& t) 
    { 
    std::cout << "generic foo" << std::endl; 
    } 
}; 
// forward declaration of specialization 
template<> void T::foo(const double& t); 

файл tmp.cpp:

#include "tmp.h" 

template <> void T::foo(const double& t) 
{ 
    std::cout << "double foo" << std::endl; 
} 

файл main.cpp:

#include "tmp.h" 
int main(int argc, const char** argv) 
{ 
    T t; 
    t.foo(1.0); 
    t.foo(1); 
    return 0; 
} 

Теперь компиляции и .cpp файлы будет работать нормально:

g++ main.cpp tmp.cpp -o tmp 
./tmp 
double foo 
generic foo 

без определения специализации:

g++ main.cpp -o tmp 
/tmp/ccpCJr3B.o: In function `main': 
main.cpp:(.text+0x1f): undefined reference to `void T::foo<double>(double const&)' 
collect2: error: ld returned 1 exit status 
+0

Это не то, что я просил, но очень полезно. Благодаря! – Iban

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