Имеет объявление Stack<T>(); для ctor по умолчанию, допустимого внутри шаблона класса

Я видел этот ответ на вопрос о SO, связанный с объявлением конструктора по умолчанию шаблона класса, в котором говорилось, что следующий код недействителен C++ из-за CWG1435:

template <class T> class Stack {
public:
  Stack<T>(); //IS THIS VALID?
};


В то время как другой отвечать сказал, что приведенный выше пример является допустимым C++. Есть 2 источника утверждения, что приведенный выше пример действителен:

  1. Внедренные имена классов:

Otherwise, it is treated as a type-name, and is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>

  1. В Конференция CppConДэн Сакс в основном показан очень похожий пример.

Итак, как мы видим, два связанных ответа делают противоположные утверждения, и я не знаю, какой из них правильный. Итак, мой вопрос, какой из двух ответов правильный. То есть является ли объявление Stack<T>(); действительным C++ или нет.

PS: я задаю свой вопрос для современного С++, что означает С++ 11 и далее.

Я бы ожидал, что вопрос будет противоположным, если бы Stack(); был действительным. Что есть, и это будет эквивалентно Stack<T>();, что вы написали в вопросе (и поэтому должно быть действительным).

Some programmer dude 22.04.2022 18:40
Получение данных из формы с помощью JavaScript - краткое руководство
Получение данных из формы с помощью JavaScript - краткое руководство
Получить данные из формы с помощью JS очень просто: вы запрашиваете элемент формы, передаете его конструктору new FormData() и, наконец, получаете...
Пользовательские правила валидации в Laravel
Пользовательские правила валидации в Laravel
Если вы хотите создать свое собственное правило валидации, Laravel предоставляет возможность сделать это. Создайте правило с помощью следующей...
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
2
1
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В вашем примере есть неквалифицированный идентификатор, который является идентификатор шаблона. Это не разрешено в последняя формулировка, конструктор должен быть представлен его внедренное имя класса.

Ваша цитата об эквивалентности между внедренное имя класса и Имя Шаблона, за которыми следуют параметры шаблона, здесь не применяется, потому что идентификатор здесь не является именем типа, это объявление конструктора.

Это определенно изменилось с C++11.

Ответ принят как подходящий

Показанный фрагмент действителен для версии Pre-C++20, но недействителен для C++20 и более поздних версий, как объяснено ниже.

До C++20

Из класс.ctor#1.2:

1 -- Constructors do not have names. In a declaration of a constructor, the declarator is a function declarator of the form:
ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:

1.2 -- in a member-declaration that belongs to the member-specification of a class template but is not a friend declaration, the id-expression is a class-name that names the current instantiation of the immediately-enclosing class template; or

(конец цитаты)

Это означает, что в C++17 нам разрешено использовать Stack<T>(); в качестве объявления конструктора.

С++ 20

От класс.ctor#1.1:

1 -- A constructor is introduced by a declaration whose declarator is a function declarator ([dcl.fct]) of the form:
ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:

1.1 -- in a member-declaration that belongs to the member-specification of a class or class template but is not a friend declaration ([class.friend]), the id-expression is the injected-class-name ([class.pre]) of the immediately-enclosing entity or

Итак, как мы видим, введенное имя класса (который в вашем примере Stack, а не Stack<T>) необходим для объявления ctor шаблона класса.

Это означает, что данный вами код недействителен для C++20.


То же самое упоминается и в diff.cpp17.класс#2:

Affected subclauses: [class.ctor] and [class.dtor]

Change: A simple-template-id is no longer valid as the declarator-id of a constructor or destructor.

Rationale: Remove potentially error-prone option for redundancy.

Effect on original feature: Valid C++ 2017 code may fail to compile in this revision of C++. For example:

template<class T>
struct A {
  A<T>();           // error: simple-template-id not allowed for constructor
  A(int);           // OK, injected-class-name used
  ~A<T>();          // error: simple-template-id not allowed for destructor
};

Является ли Stack<T> идентификатором-выражением?

n. 1.8e9-where's-my-share m. 24.04.2022 09:18

@n.1.8e9-где-мой-шарем. Да, Stack<T> — это идентификатор шаблона, который является неквалифицированным идентификатором и, следовательно, идентификатором-выражением.

Anoop Rana 24.04.2022 09:31

Другие вопросы по теме