Допустимо ли писать список параметров типа шаблона в объявлении конструктора? - PullRequest
6 голосов
/ 26 декабря 2011

Старый GCC 4.1.2 принимает , а новый GCC 4.5.1 принимает , следующую программу.

Но действительно ли это правильно? Что стандарт говорит об объявлении конструктора с параметром шаблона типа, подобным этому?

(мне интересно, что мне не разрешено делать то же самое в определении вне строки .)

#include <iostream>
template <typename T>
struct Foo {
   Foo<T>(); // <---
};

template <typename T>
Foo<T>::Foo() {
  std::cout << ":)";
}

int main() {
   Foo<int> f;
}

Причина, по которой я спрашиваю, состоит в том, что в комментариях к этому ответу было предложено, что GCC может быть здесь ошибочным.

1 Ответ

3 голосов
/ 26 декабря 2011

Я отправлю по почте копию возможного 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> может быть проанализирован только как список аргументов шаблона. Если среди ваших конструкторов нет шаблона, ваш код будет недействительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...