Pregunta

¿Es posible el siguiente diseño?:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

Ahora, si fuera posible, hiciera algunas especializaciones explícitas para Dosomething para que al final tuviera algunas versiones como a continuación:

void doSomething<int>(){
 //do something
}
void doSomething<double>(){
 //do something
}
...etc

Lo que parece imposible, no puedo encontrar ninguna sintaxis para hacer el trabajo, entonces pensé que tal vez el diseño debería ser lo que sigue para que todos los argumentos de plantilla se pasen a la clase de plantilla en sí:

template <typename T,typename Z>
class Test{
 public:
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

Luego probé especialización parcial que ni siquiera compiló:

template <typename T>
void Test<T,int>::doSomething(){
 //do something
}
template <typename T>
void Test<T,double>::doSomething(){
 //do something
}
...etc

Recibí los siguientes errores para especialización explícita:
Error#1: Lista de argumentos de plantilla El siguiente nombre de plantilla de clase debe enumerar los parámetros en el orden utilizado en la lista de parámetros de plantilla.
Error#2: 'Container1': muy pocos argumentos de plantilla.

¿Fue útil?

Solución

Para especializarse explícitamente doSomething También tienes que especializarte explícitamente Test.

De 14.7.3/18:

En una declaración de especialización explícita para un miembro de una plantilla de clase o una plantilla de miembro que aparece en el alcance del espacio de nombres, la plantilla de miembro y algunas de sus plantillas de clase de cierre pueden permanecer sin especializar, Excepto que la declaración no especializará explícitamente una plantilla de miembro de la clase si sus plantillas de clase adjuntas no están explícitamente especializadas también.

Otros consejos

No puede especializar explícitamente una plantilla de miembro a menos que sus plantillas de clase adjuntas también estén explícitamente especializadas.

Entonces, solo algo como esto funcionará:

template<> template<>
void Test<int>::doSomething<int>()
{
}

siempre puedes hacer que la función esté en línea

template <class T>
class Test
{
public:
 template <class Z>
 void doSomething() { cout << "default" << endl; }

 template<>
 void doSomething<int>() { cout << "int" << endl;}
 template<>
 void doSomething<double>() { cout << "double" << endl; }
private:
 T obj;
};

Creo que este es exigente. Supongo que no puedes hacerlo, lee este.

No estoy seguro si esto es un error en G ++, pero esto compila y produce lo que espero.

#include<typeinfo>
#include<iostream>

template<typename T>
class Test
{
public:
    template<typename Z>
    void doSomething();

private:
    T obj;
};

template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
    Z val;
    std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}

int main(int argc, char *argv[])
{
    Test<double> a;
    a.doSomething<int>();
    a.doSomething<double>();
}

Icecrime publicó una respuesta temporal y se compila debido a algún error probablemente por Visual C ++ 2008:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
 //do something
}

Sin embargo, verifique su respuesta actual. Lo curioso, al menos con VC ++ 2008, no hay problemas para compilarse cuando se especializa con definiciones en línea, pero para especializaciones con definiciones no en línea, una vez que hay más de una versión, no se compila correctamente.

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