2011-08-03 13 views
6

Estoy leyendo Vandevoorde y Josuttis "C++ Templates The Complete Guide" (que parece bastante bueno, por cierto). Este reclamo (sección 3.3) parece estar equivocado and is not in the published errata:¿Este libro de texto está equivocado? Especializando algunas funciones miembro pero no otras

Si especializa una plantilla de clase, también debe especializar todas las funciones de miembros. Aunque es posible especializar una función de miembro único, una vez que lo haya hecho, ya no podrá especializar toda la clase.

Sin embargo, las siguientes compilaciones de gcc plantilla

<typename T> 
struct C { 
    T foo(); 
    T bar(); 
}; 

template <> 
struct C<int> { 
    int foo(); 
    int bar() {return 4;} 
}; 

template <typename T> 
T C<T> :: foo() {return 0;} 

template <typename T> 
T C<T> :: bar() {return 1;} 

int C<int> :: foo() {return 2;} 

template <> 
float C<float> :: bar() {return 3;} 

#include <cassert> 

int main() { 
    C<int> i; 
    C<float> f; 
    assert (2 == i .foo()); 
    assert (0 == f .foo()); 
    assert (4 == i .bar()); 
    assert (3 == f .bar()); 
} 

que se han especializado C<int>::foo y C<float>::bar también lo es el libro de texto mal, es gcc ir más allá de la norma, o estoy malentendido toda la situación?

Gracias.

+0

Usted malinterpretado la regla. Una vez que haya especializado una función miembro, no podrá especializar una clase en el mismo tipo, no en todos los demás tipos. –

Respuesta

5

No se puede hacer esto:

template <typename T> struct C 
{ 
    T foo()  { return 0;} 
    T bar()  { return 1;} 
}; 

// partial specialization of foo on C<int> 
template <> 
int C<int> :: foo() {return 2;} 

// partial specialization of bar on C<float> 
template <> 
float C<float> :: bar() {return 3;} 

// will not compile, C<int> already partially specialized 
template <> 
struct C<int> 
{ 
    int foo() {return 10;} 
    int bar() {return 10;} 
}; 
+1

Este es un error de redefinición ordinario, nada que ver con las plantillas. ¿Es por esto que estoy confundido? ¿Simplemente porque fue mencionado en el contexto de las plantillas? Buena pena ... – spraff

+0

En este contexto, puede pensar así, sí. Si elimina la implementación de 'foo()' en la especialización de 'C ', simplemente tratará la especialización parcial como la implementación de esta función. – Chad

4

No, el libro no está mal. Su comprensión es, me temo :)

En este caso se han especializado sólo el 1 función miembro-foo para C<int> y bar para C<float>

Ahora no se puede especializar de forma explícita o C<int>C<float>. Pero puede especializarse C<char>

+0

Por favor vea mi pregunta actualizada. Ahora he especializado una función (barra) para 'C ' y se le ha dado una especialización completa para 'C ' - ¿no *** este *** está en contradicción con el libro de texto? – spraff

+0

No, su "especialización parcial" de C :: foo() es simplemente la definición de la versión totalmente especializada. Ver mi respuesta a continuación para más detalles. – Chad

Cuestiones relacionadas