voy a poner una copia de correo de una posible DR poco me envió en Navidad aquí
está bien formado el siguiente código?
template<typename T>
struct A {
A<T>();
};
Los varios compiladores que he probado (sonido metálico, g ++ y conline comeau) aceptar esto. De hecho 12.1 no prohíbe esto (A<T>
es un nombre de esa clase y no es un nombre typedef), pero 8.3p1 dice
un rotundo-id ocurriendo en un declarador-id será un simple identificador excepto para la declaración de algunas funciones especiales (12.3, 12.4 , 13.5) ...
un constructor es una función miembro especial, pero la lista de referencias cruzadas no incluye 12.1. ¿Eso significa que el código anterior está mal formado? ¿O es esto una omisión accidental?
Si hace lo mismo en una definición fuera de línea, intentará pasar argumentos de plantilla a un constructor. Este es un código válido
struct A {
template<typename T> A();
};
template<> A::A<int>() { }
La especificación dice que cuando el nombre de la clase inyectada se utiliza en un nombre calificado cuando se mira en el ámbito de la clase (al igual que en A::A
), a continuación, cuando la búsqueda de nombres acepta la función nombres/constructor , la referencia del nombre de clase inyectado será traducida para ser resuelta al constructor (es) de esa clase (si el contexto de búsqueda de nombre solo acepta tipos, entonces el nombre seguirá siendo el nombre de clase inyectado, y denotará el tipo de clase). Después de A::A
, la búsqueda del nombre está completa y proporciona el constructor. El <int>
solo se puede analizar como una lista de argumentos de plantilla. Si no hay una plantilla entre sus constructores, su código no será válido.
FWIW, compila y ejecuta en GCC 4.6.1 también. – Mat
Presumiblemente debido a 12.1/1: "La sintaxis usa ... el nombre de clase del constructor ...", esta pregunta equivale a "es' Foo '¿el nombre de clase?" –
@SteveJessop: ... "y, de ser así, ¿por qué no se acepta en la definición?" –