Я отправлю по почте копию возможного DR, который я недавно разослал на Рождество здесь
Правильно ли сформирован следующий код?
template<typename T>
struct A {
A<T>();
};
Несколько протестированных мной компиляторов (clang, g ++ и comeau conline)
принять это. Действительно, 12.1 не запрещает это (A<T>
это имя того
class и не является typedef-именем), но 8.3p1 говорит
Неквалифицированный идентификатор, встречающийся в идентификаторе объявления, должен быть простым
идентификатор за исключением объявления некоторых специальных функций (12.3,
12,4, 13,5) ...
Конструктор - это специальная функция-член, но список перекрестных
ссылки не включают 12.1. Означает ли это, что приведенный выше код
плохо сформирован? Или это случайное упущение?
Если вы сделаете то же самое в определении вне строки, вы попытаетесь передать аргументы шаблона конструктору. Это действительный код
struct A {
template<typename T> A();
};
template<> A::A<int>() { }
В спецификации сказано, что когда имя введенного класса используется в квалифицированном имени при просмотре области действия класса (как и в A::A
), тогда, когда поиск имени принимает имена функций / конструкторов, ссылка на введенное имя класса будет преобразован для разрешения в конструктор (ы) этого класса (если контекст поиска имени принимает только типы, то имя останется именем внедренного класса и будет обозначать тип класса). После A::A
поиск имени завершается и выдает конструктор. <int>
может быть проанализирован только как список аргументов шаблона. Если среди ваших конструкторов нет шаблона, ваш код будет недействительным.