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

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

Эффекты не определены ... если неполный тип используется в качестве аргумента шаблона при создании экземпляра компонента шаблона,если специально не разрешено для этого компонента (C ++ 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() не используется или не определен как odr?

Аналогично, вызывает ли следующее создание экземпляра шаблона класса std::vector?Я использую std::vector в этих примерах, вопрос в равной степени относится ко всем шаблонам.

Ответы [ 2 ]

5 голосов
/ 11 октября 2011

§ 14.7.1 \ 1 Неявная реализация [temp.inst]

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

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

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

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

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

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

2 голосов
/ 05 февраля 2012

Нет, шаблон не создается.Ответ 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 указывается, что неполный класс допустим для этого первого прохода, но не для второго.

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

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