especialización explícita de la función de miembro de clase de plantilla

Necesito especializar la función de miembro de plantilla para algún tipo (digamos doble ). Funciona bien, mientras que la clase X sí misma no es una clase de plantilla, pero cuando lo hago, la plantilla GCC comienza a dar errores en tiempo de comstackción.

 #include  #include  template  class X { public: template  void get_as(); }; template  void X::get_as() { } int main() { X x; x.get_as(); } 

Aquí está el mensaje de error

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

¿Cómo puedo solucionar eso y cuál es el problema aquí?

Gracias por adelantado.

No funciona de esa manera. Debería decir lo siguiente, pero no es correcto

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

Los miembros explícitamente especializados necesitan que las plantillas de clase que los rodean también estén explícitamente especializadas. Por lo tanto, debe decir lo siguiente, que solo especializaría al miembro para X .

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

Si desea mantener la plantilla circundante no especializada, tiene varias opciones. Prefiero sobrecargas

 template  class X { template struct type { }; public: template  void get_as() { get_as(type()); } private: template void get_as(type) { } void get_as(type) { } }; 

Si uno puede usar std::enable_if podemos confiar en SFINAE (la falla de sustitución no es un error)

eso funcionaría así:

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

Lo feo es que, con todas estas enable_if, solo una especialización debe estar disponible para el comstackdor, de lo contrario, surgirá un error de desambiguación. Es por eso que el comportamiento predeterminado “obtener como T” también necesita habilitar.