Error “uso no válido de tipo incompleto” con especialización de plantilla parcial

El siguiente código:

template  struct foo { void bar(); }; template  void foo ::bar() { } 

me da el error

 invalid use of incomplete type 'struct foo' declaration of 'struct foo' 

(Estoy usando gcc.) ¿Está mal mi syntax de especialización parcial? Tenga en cuenta que si elimino el segundo argumento:

 template  struct foo { void bar(); }; template  void foo ::bar() { } 

entonces comstack correctamente

No puedes especializar parcialmente una función. Si desea hacerlo en una función miembro, debe especializar parcialmente toda la plantilla (sí, es irritante). En una clase de plantilla grande, para especializar parcialmente una función, necesitaría una solución alternativa. Quizás una estructura de miembros con plantilla (por ejemplo, template struct Nested ) funcionaría. O bien, puede intentar derivar de otra plantilla que se especialice parcialmente (funciona si usa la notación this->member , de lo contrario, encontrará errores de comstackción).

Aunque coppro ya mencionó dos soluciones y Anonymous explicó la segunda, tardé bastante tiempo en entender la primera. Tal vez el siguiente código sea útil para alguien que tropiece con este sitio, que aún ocupa un lugar destacado en Google, como yo. El ejemplo (pasar un vector / matriz / elemento individual de numericalT como dataT y luego acceder a él vía [] o directamente) es, por supuesto, un tanto artificial, pero debe ilustrar cómo realmente puede acercarse a la especialización parcial de una función miembro envolviéndola en una clase parcialmente especializada.

 /* The following circumvents the impossible partial specialization of a member function actualClass::access as well as the non-nonsensical full specialisation of the possibly very big actualClass. */ //helper: template  class specialised{ public: numericalT& access(dataT& x, const unsigned int index){return x[index];} }; //partial specialisation: template  class specialised{ public: numericalT& access(dataT& x, const unsigned int index){return x;} }; //your actual class: template  class actualClass{ private: dataT x; specialised accessor; public: //... for(int i=0;i 

Si necesita especializar parcialmente un constructor, puede intentar algo como:

 template  struct thingBase { //Data members and other stuff. }; template  struct thing : thingBase {}; template  struct thing : thingBase { thing(T * param1, wchar_t * param2) { //Special construction if N equals 42. } }; 

Nota: esto fue anónimo de algo en lo que estoy trabajando. También puede usar esto cuando tenga una clase de plantilla con muchos y muchos miembros y solo quiera agregar una función.