2011-11-03 12 views
6

El estándar ISO 98/03 (sección 14.3.1) parece prohibir el uso de un tipo con enlace interno como parámetro de plantilla. (Consulte el ejemplo a continuación). El estándar C++ 11 no. G ++ - usando el viejo estándar - lo permite. ¿Estoy malinterpretando el estándar 03 o g ++ solo dejo pasar esta diapositiva?Tipo interno como argumento de plantilla

namespace 
{ 
    struct hidden { }; 
} 

template<typename T> 
struct S 
{ 
    T t; 
}; 

int main() 
{ 
    S<hidden> s; 
    return 0; 
} 
+0

Qué g ++ versión? Podría ser una extensión –

Respuesta

7

tiene usted razón de que C++ 03 no permite el uso de un tipo de enlace interno como un parámetro de tipo de plantilla, mientras que C++ 11 hace.

Parece recordar, sin embargo, que las definiciones dentro del espacio de nombres anónimo aún tienen enlaces externos.


Sí, sección 3.5 [basic.link] dice

Un nombre que tiene alcance de espacio de nombres (3.3.5) tiene enlace interno si es el nombre de

  • un objeto, de referencia, la función o plantilla de función que se declara explícitamente estática o,
  • un objeto o referencia explícitamente declarado const y ninguno explícitamente declarado extern ni previamente declarado tener un enlace externo; o
  • miembro de datos de una unión anónima.

Un nombre que tiene alcance de espacio de nombres tiene enlazado externo si es el nombre de

  • un objeto o de referencia, a menos que tenga enlace interno; o
  • una función, a menos que tenga un enlace interno; o
  • una clase con nombre (cláusula 9), o una clase sin nombre definida en una declaración typedef en la cual la clase tiene el nombre typedef para fines de vinculación (7.1.3); o
  • una enumeración nombrada (7.2), o una enumeración sin nombre definida en una declaración typedef en la que la enumeración tiene el nombre typedef para fines de vinculación (7.1.3); o
  • enumerador que pertenece a una enumeración con enlace externo; o
  • una plantilla, a menos que sea una plantilla de función que tenga un enlace interno (cláusula 14); o
  • un espacio de nombre (7.3), a menos que se declare dentro de un espacio de nombre sin nombre.

tiene una clase llamada al alcance de espacio de nombres, que tiene enlazado externo.

y la nota en la parte inferior de la página 115 de la Norma ISO/IEC 14882: 2003 aclara:

Aunque las entidades en un espacio de nombres sin nombre podrían tener vinculación externa, que están calificados de manera efectiva por un nombre único para su traducción unidad y, por lo tanto, nunca se puede ver desde ninguna otra unidad de traducción.

Si tiene otra versión, intente buscar en la sección 7.3.1.1 [namespace.unnamed]

4

Ese no es un ejemplo válido de la regla. La clase hidden en su ejemplo tiene external vinculación. (Tiene un nombre exclusivo generado por el compilador tal que nada fuera de la unidad de traducción actual realidad puede enlazar con él, pero aún así es externo.)

La norma da un ejemplo de un tipo de locales:

template <class T> class X { /* ... */ }; 
void f() 
{ 
    struct S { /* ... */ }; 

    X<S> x3; // error: local type used as template-argument 
    X<S*> x4; // error: pointer to local type used as template-argument 
} 
Cuestiones relacionadas