c++ - template - Especializando una clase de plantilla como una estructura.
template < class tipos>& gt (2)
En primer lugar, aquí está la respuesta a 2. tomada del párrafo 4 de [temp.class] 14.5.1:
En una redeclaración, especialización parcial, especialización explícita o creación de instancias explícita de una plantilla de clase, la clave de clase coincidirá con la declaración de plantilla de clase original.
Sin embargo, struct
y class
se refieren a la misma clave de clase de acuerdo con 7.1.6.3 [dcl.type.elab] párrafo 3 última oración:
La clave de clase o la palabra clave de enumeración presente en el especificador de tipo elaborado se acordará en especie con la declaración a la que se refiere el nombre en el especificador de tipo elaborado. [...] Por lo tanto, en cualquier especificador de tipo elaborado, la palabra clave enum se usará para referirse a una enumeración, la clave de clase union se usará para referirse a una unión, y la clase o struct class-key se utilizará para referirse a una clase declarada usando la clase o estructura class-key.
Al probar g ++, clang y EDG, todos están de acuerdo en que es posible especializar una plantilla declarada como struct
como class
. Sin embargo, clang advierte acerca de haber cambiado de struct
a class
o viceversa. En base a esto, la biblioteca estándar es libre de elegir cualquier palabra clave que considere adecuada para la definición. Obviamente, si el compilador rechaza el código como resultado, algo está seriamente dañado, pero creo que es el compilador en lugar de la biblioteca el que está en error en este caso.
Estaba especializando std::hash
para un tipo definido por el usuario usando:
template<>
struct hash<...> {...};
Cuando VC10 me saludó con la advertencia:
advertencia C4099: ''std :: hash <_Kty>'': nombre del tipo visto por primera vez usando ''clase'' ahora visto usando ''struct''
y descubrí que su biblioteca estándar declara std::hash
como class
, mientras que el estándar (o el último borrador gratuito que tengo) lo declara como struct
.
Bueno, por supuesto, sé que una estructura no es diferente de una clase (excepto los diferentes tipos de herencia y acceso predeterminados). Pero mis preguntas son:
- ¿VC10 viola el estándar aquí o es gratis el intercambio de
struct
porclass
en cualquier componente estándar de la biblioteca (siempre que los tipos de acceso requeridos para los miembros se mantengan consistentes, por supuesto)? - ¿Es legal especializar una clase de plantilla como una estructura y viceversa o esto trae problemas con la resolución de nombres y similares (al menos VC10 cree que vale la pena una advertencia)?
Para 1: No estoy seguro, pero creo que es un error.
Para 2: No te preocupes, no debería dar lugar a ningún comportamiento extraño. Solo tenga cuidado con los ámbitos de funciones que defina. En cuanto a la advertencia, en realidad es bastante general (es decir, no está hecho especialmente para plantillas), por lo que no me importaría mucho.
Edición: vea también la respuesta a this pregunta, que básicamente dice que no hace ninguna diferencia en el estándar, pero algunos compiladores pueden comportarse de manera extraña.