Especialização explícita no escopo não-namespace

template class CConstraint { public: CConstraint() { } virtual ~CConstraint() { } template  void Verify(int position, int constraints[]) { } template  void Verify(int, int[]) { } }; 

Compilar isso em g ++ fornece o seguinte erro:

Especialização explícita no escopo não-namespace ‘class CConstraint’

Em VC, compila bem. Alguém pode por favor me avise a solução?

O VC ++ não é compatível neste caso – as especializações explícitas devem estar no escopo do namespace. C ++ 03, §14.7.3 / 2 :

Uma especialização explícita deve ser declarada no namespace do qual o modelo é membro ou, para modelos de membro, no namespace do qual a class envolvente ou modelo de class envolvente é membro.
Uma especialização explícita de uma function de membro, class de membro ou membro de dados estático de um modelo de class deve ser declarada no namespace do qual o modelo de class é um membro.

Além disso, você tem o problema de não poder especializar as funções de membro sem explicitamente especializar a class de contenção devido ao C ++ 03, §14.7.3 / 3 , portanto uma solução seria deixar o Verify() encaminhar para um, possivelmente especializado, function livre:

 namespace detail { template  void Verify (int, int[]) {} template <> void Verify(int, int[]) {} } template class CConstraint { // ... template  void Verify(int position, int constraints[]) { detail::Verify(position, constraints); } }; 

Outra maneira de resolvê-lo é delegando a uma function privada e sobrecarregando essa function. Dessa forma, você ainda tem access aos dados do membro *this e ao tipo de parâmetro de template externo.

 template struct identity { typedef T type; }; template class CConstraint { public: template  void Verify(int position, int constraints[]) { Verify(position, constraints, identity()); } private: template void Verify(int, int[], identity) { } void Verify(int, int[], identity) { } }; 

Apenas pegue a especialização de modelo fora da declaração de class. O gcc não permite especialização de modelos in-line.

Como outra opção, apenas excluir o modelo de linha <> parece funcionar para mim.

Melhor ainda: você pode combinar especialização parcial com argumentos de modelo padrão. Desta forma, modificações no código VC ++ são menores, porque as chamadas para a function especializada não precisam ser modificadas.

 template  void Verify(int position, int constraints[]) { } template  void Verify(int, int[]) { } 

Talvez não seja possível explicitamente especializar o modelo de membro, mas você pode especializá-lo parcialmente . Se você adicionar um segundo parâmetro “int dummyParam” e também adicioná-lo à especialização, ele deverá funcionar com os dois compiladores.

Não que eu soubesse disso há mais de 10 segundos atrás, mas pesquisando sobre o mesmo erro, encontrei este link e ele funcionou para a especialização de modelo de membro.