显式的模板类成员函数的特化

我需要专门化一些types的模板成员函数(比方说double )。 它工作正常,而类X本身不是一个模板类,但是当我做模板GCC开始给编译时错误。

 #include <iostream> #include <cmath> template <class C> class X { public: template <class T> void get_as(); }; template <class C> void X<C>::get_as<double>() { } int main() { X<int> x; x.get_as(); } 

这里是错误信息

 source.cpp:11:27: error: template-id 'get_as<double>' in declaration of primary template source.cpp:11:6: error: prototype for 'void X<C>::get_as()' does not match any in class 'X<C>' source.cpp:7:35: error: candidate is: template<class C> template<class T> void X::get_as() 

我怎样才能解决这个问题,这里有什么问题?

提前致谢。

这种方式不行。 你需要说以下内容,但这是正确的

 template <class C> template<> void X<C>::get_as<double>() { } 

明确专业化的成员也需要他们周围的类模板。 所以你需要说下面的内容,这将只针对X<int>的成员。

 template <> template<> void X<int>::get_as<double>() { } 

如果你想保持周围的模板非专业化,你有几个select。 我更喜欢重载

 template <class C> class X { template<typename T> struct type { }; public: template <class T> void get_as() { get_as(type<T>()); } private: template<typename T> void get_as(type<T>) { } void get_as(type<double>) { } }; 

如果有人能够使用std::enable_if我们可以依靠SFINAE(replace失败不是一个错误)

那会像这样工作:

 #include <iostream> #include <type_traits> template <class C> class X { public: template <class T, typename std::enable_if< ! std::is_same<double,T>::value>::type * = nullptr > void get_as(){ std::cout << "get as T" << std::endl; } template <class T, typename std::enable_if< std::is_same<double,T>::value>::type * = nullptr > void get_as(){ std::cout << "get as double" << std::endl; } }; int main() { X<int> d; d.get_as<double>(); return 0; } 

丑陋的是,所有这些enable_if只有一个专业化需要可用的编译器,否则消除歧义的错误将出现。 这就是为什么默认行为“得到T”还需要启用if。

首先:您的类模板中未声明get_as专用,以便稍后在代码中进行定义。 所以首先你需要这样做:

 template <class C> class X { public: template <class T> void get_as(); template <> void get_as<double>(); }; 

然后定义专业化:

 template <class C> template <> void X<C>::get_as<double>() { .... } 

但我会这样定义它:

 template <class C> class X { public: template <class T> void get_as() { // default implementation } template <> void get_as<double>() { // specialized implementation } }; 

抱怨上面不行!

编辑:

事实certificate,function模板专门化是不允许在非命名空间范围,即在类,类模板等。

所以你可以把它作为命名空间范围的函数模板:

 template <class C> class X { public: } template <class T, class C> void get_as( X<C>& obj ) { // default implementation } template <class C> void get_as<double,C>( X<C>& obj ) { // specialized implementation }