c++ gcc templates partial-specialization

c++ - Error "uso no válido de tipo incompleto" con especialización de plantilla parcial



gcc templates (3)

El siguiente código:

template <typename S, typename T> struct foo { void bar(); }; template <typename T> void foo <int, T>::bar() { }

me da el error

invalid use of incomplete type ''struct foo<int, T>'' declaration of ''struct foo<int, T>''

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

template <typename S> struct foo { void bar(); }; template <> void foo <int>::bar() { }

entonces compila correctamente


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<dataT,numericalT,1>::access as well as the non-nonsensical full specialisation of the possibly very big actualClass. */ //helper: template <typename dataT, typename numericalT, unsigned int dataDim> class specialised{ public: numericalT& access(dataT& x, const unsigned int index){return x[index];} }; //partial specialisation: template <typename dataT, typename numericalT> class specialised<dataT,numericalT,1>{ public: numericalT& access(dataT& x, const unsigned int index){return x;} }; //your actual class: template <typename dataT, typename numericalT, unsigned int dataDim> class actualClass{ private: dataT x; specialised<dataT,numericalT,dataDim> accessor; public: //... for(int i=0;i<dataDim;++i) ...accessor.access(x,i) ... };


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 <typename U = T> 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 compilación).


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

template <class T, int N> struct thingBase { //Data members and other stuff. }; template <class T, int N> struct thing : thingBase<T, N> {}; template <class T> struct thing<T, 42> : thingBase<T, 42> { 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.