Pregunta

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). ¿Mi sintaxis para la especialización parcial es incorrecta? Tenga en cuenta que si elimino el segundo argumento:

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

template <>
void foo <int>::bar() {
}

luego se compila correctamente.

¿Fue útil?

Solución

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 con plantilla grande, para especializar parcialmente una función, necesitaría una solución. Quizás una estructura miembro con plantilla (por ejemplo, template < typename U = T > struct Nested ) podría funcionar. O bien, puede intentar derivar de otra plantilla que se especializa parcialmente (funciona si usa la notación this- > member , de lo contrario, encontrará errores de compilación).

Otros consejos

Aunque coppro ya mencionó dos soluciones y Anonymous explicó la segunda, me tomó bastante tiempo entender la primera. Tal vez el siguiente código sea útil para alguien que se encuentre en este sitio, que todavía ocupa un lugar alto en Google, como yo. El ejemplo (pasar un elemento vector / array / único de T numérico como dataT y luego acceder a él a través de [] o directamente) es un poco artificial, pero debería ilustrar cómo puede realmente 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) ...
};

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 desde algo en lo que estoy trabajando. También puede usar esto cuando tiene una clase de plantilla con muchos y muchos miembros y solo desea agregar una función.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top