2010-11-25 13 views
6

está siguiendo el diseño posible ?:¿Cómo debo hacer esta especialización explícita?

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

Ahora bien, si era posible me gustaría hacer algunas especializaciones explícitas para doSomething de manera que al final tendría algunas versiones como a continuación:

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

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

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

Luego probé la especialización parcial que ni siquiera compilar:

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

me los siguientes errores de especialización explícita:
error # 1: Modelo de la lista de argumentos siguiente nombre de la plantilla de clase debe listar parámetros en el orden acostumbrado en la lista de parámetros de la plantilla.
error # 2: 'Container1': muy pocos argumentos de plantilla.

+0

¿No se puede sobrecargar doSomething en una etiqueta y tener una visión general con una elipsis o una plantilla genérica? – Tomek

+0

@ Tomek_No entiendes lo que quieres decir, por cierto, el foco está en las plantillas. – Pooria

Respuesta

6

Para especializarse explícitamente en doSomething, también debe especializarse explícitamente en Test.

De 14.7.3/18:

En una declaración explícita especialización para un miembro de una plantilla de clase o miembro de una plantilla que aparece en su alcance espacio de nombres, miembro de la plantilla y algunos de sus adjuntando plantillas de clase puede permanecer no especializado, excepto que la declaración no explícitamente deberá especializarse una plantilla miembro de la clase si sus plantillas de clase envolvente no son explícitamente especializado también.

+0

Compruebe mi respuesta también. – Pooria

+0

Como una nota lateral, las plantillas de subclase pueden ser explícitamente especializadas sin que todas las plantillas de clase adjuntas estén explícitamente especializadas. – Pooria

2

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

Por lo que sólo algo como esto funcionará:

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

No, no compila. – Simone

+0

Smiljanic_ "No se puede especializar explícitamente una plantilla de miembro a menos que las plantillas de clase adjuntas también estén explícitamente especializadas". No, eso no está bien, verifica mi respuesta. – Pooria

+3

@Pooria: Sí, es cierto, consulte la respuesta de icecrime para la referencia. –

0

Creo que éste es exigente. Supongo que no puedes hacerlo, lee this.

-2

icecrime registró una respuesta temporal y que se compila debido a algún error, probablemente por C++ Visual 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 
} 

Compruebe su respuesta actual sin embargo. Lo gracioso al menos con VC++ 2008 es que no hay problemas para compilar al especializarse con definiciones en línea, pero para las especializaciones con definiciones no en línea una vez que hay más de una versión no se compila correctamente.

+1

En mi versión de g ++ no compila. – Simone

+0

¿por qué diablos downvote cuando se compila perfectamente en Visual C++ 2008? – Pooria

+1

Este definitivamente no debería funcionar. Y, de hecho, no en MSVC10. –

1

siempre se puede hacer la función 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; 
}; 
+1

Por cierto, esto se compila en C++ 2008 visual debido a algún error, supongo. ;). – Pooria

+0

compilado para mí también en C++ visual, es por eso que lo escribí. También funciona si lo ejecuta en Visual C++ 2010, por lo que no lo merezco -1 :) – hidayat

+0

Lo gracioso al menos con VC++ 2008 es que no hay problemas compilando al especializarse con definiciones en línea, pero para especializaciones con definiciones no en línea una vez hay más de una versión que no se compila con éxito. – Pooria

0

No estoy seguro si esto es un error en g ++ pero esto compila y producir 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>(); 
} 
+0

Eso no es especialización explícita, por lo que no hay ningún error. – Pooria

+0

Sí, solo define la función del miembro con plantilla. Intentó Nikola Smiljanić y funciona con g ++. – Tobias

Cuestiones relacionadas