especialização explícita da function de membro de class de modelo

Preciso especializar a function de membro de modelo para algum tipo (digamos, duplo ). Ele funciona bem, enquanto a própria class X não é uma class de modelo, mas quando eu faço isso, o GCC começa a fornecer erros em tempo de compilation.

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

aqui está a mensagem de erro

 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() 

Como posso corrigir isso e qual é o problema aqui?

Desde já, obrigado.

Não funciona assim. Você precisaria dizer o seguinte, mas não está correto

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

Membros explicitamente especializados precisam que seus modelos de classs adjacentes também sejam explicitamente especializados. Então você precisa dizer o seguinte, que apenas especializaria o membro para X .

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

Se você quiser manter o modelo circundante não especializado, você tem várias opções. Eu prefiro 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) { } }; 

Se alguém é capaz de usar std::enable_if poderíamos confiar em SFINAE (falha de substituição não é um erro)

que funcionaria assim:

 #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; } 

O mais feio é que, com todas essas habilitações, uma única especialização precisa estar disponível para o compilador, caso contrário, um erro de desambiguação surgirá. É por isso que o comportamento padrão “get as T” também precisa de um enable if.