Подтвердить что ты не робот

В объявлении "std::vector <X> f();", является ли "std::vector <X>" экземпляром?

В стандарте языка С++ указано следующее относительно компонентов шаблона в стандартной библиотеке:

Эффекты undefined... если неполный тип используется в качестве аргумента шаблона при создании экземпляра компонента шаблона, если это специально не разрешено для этого компонента (С++ 11 §17.6.4.8/2).

Является ли следующее создание экземпляра шаблона класса std::vector?

class X;
std::vector<X> f(); // Declaration only; we will define it when X is complete

Чтобы спросить об этом по-другому, в объявлении функции std::vector<X> f();, есть std::vector, созданный с аргументом X? Или, std::vector<X> не создается, пока f() не используется или не определено?

Аналогично, вызывает ли следующая процедура создания шаблона класса std::vector?

class X;
typedef std::vector<X> XVector; // We will complete X before we use XVector

Пока я использую std::vector в этих примерах, вопрос одинаково применим ко всем шаблонам.

4b9b3361

Ответ 1

§ 14.7.1\1 Неявное создание экземпляра [temp.inst]

Если спецификация шаблона класса явно не указана (14.7.2) или явно специализированный (14.7.3), класс специализация шаблона неявно создается, когда специализация ссылается в контексте, который требует полностью определенный тип объекта или когда полнота класса type влияет на семантику программы. Неявное создание специализации шаблона шаблона вызывает неявное создание деклараций, но не определений или аргументов по умолчанию, функций-членов класса, классов-членов, статических элементов данных и шаблоны участников; и это вызывает неявное создание определения членских анонимных союзов. Если член класса шаблон или шаблон-член был явно инстанцирован или явно специализированный, специализация члена неявно создается, когда специализация ссылается в контексте, который требует определения члена,, в частности, инициализация (и любые связанные с ней побочные эффекты) статических данных член не возникает, если сам статический элемент данных не используется в способ, который требует определения статического члена данных.

§ 8.3.5\9 Функции [dcl.fct]

Типы не должны определяться в обратном порядке или в параметрах. Тип параметр или тип возврата для функции определение не должны быть неполный тип класса (возможно, cv-квалифицированный), если функция определение вложен в спецификацию участника для этого класса (включая определения в вложенных классах, определенных в классе).

§ 3.1\2 Объявления и определения [basic.def]

Объявление - это определение, если оно не объявляет функцию без указав тело функций (8.4),, он содержит спецификатор extern (7.1.1) или спецификацией привязки25 (7.5), и ни инициализатор ни тело функции, он объявляет статический член данных в классе (9.4), это объявление имени класса (9.1), это opaque-enum-declaration (7.2), или это объявление typedef (7.1.3),использование-декларация (7.3.3), static_assert-декларация (раздел 7), декларация атрибута (раздел 7), декларация с пустым (раздел 7), или директиву (7.3.4).

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

Ответ 2

Нет, он не создает экземпляр шаблона. Ответ Mooing Duck предоставляет все необходимые кавычки, но вот какой-то анализ.

Активация по умолчанию не может произойти, если ничего не существует, чтобы потребовать полностью определенный тип (§14.7.1/1). Определения функций специально требуют полных типов (§8.3.5/9), но вопрос заключается в том, требует ли другая часть стандарта для других объявлений.

Но существует специальное исключение для определений, которое показывает, что объявления без определения действительно различны:

Тип параметра или тип возвращаемого значения для определения функции не должен быть неполным типом класса (возможно, с квалификацией cv), если определение функции не вложено в спецификацию элемента для этого класса (включая определения в вложенных классах, определенных внутри класса).

Что особенного в определениях функций внутри спецификаций членов? Поскольку спецификация-член не может объявить одну и ту же функцию дважды (§9.2/1), а тела-члены-члены обрабатываются после всех объявлений-членов (§3.3.7/1.1). По сути, определение функции вложенных функций рассматривается как объявление во время первого прохода, а затем определение после обработки всей спецификации-члена и класс завершен (§9.2/2). И в §8.3.5/9 указано, что неполный класс допустим для этого первого прохода, но не второго.

Очень сложно выполнить исчерпывающий, окончательный поиск стандартных правил для объявлений функций и экземпляров. Но этот пример, хотя он ограничен функциями-членами и полнотой охватывающего типа, может разумно распространяться на другие функции и типы. В любом случае, это довольно хорошее свидетельство различия.