Код: Выделить всё
template
class MyType {};
Я особенно рассматриваю §6.3( 13.13) N4860:
В каждом таком определении [...] аргумент шаблона по умолчанию
, используемый шаблоном (неявным или явным) -id или simple-template-id обрабатываются так, как будто последовательность его токенов присутствовала в определении D; то есть аргумент по умолчанию или аргумент шаблона по умолчанию
подпадает под требования, описанные в этом параграфе (рекурсивно).
которые я читаю как , decltype([]{}) является частью объявленного типа, который затем является примером, явно помеченным как недействительный в исходной статье (§4). Правильно ли я это прочитал?
Редактировать 1: вот еще одна цитата из того же параграфа стандарта, которая меня очень сбивает с толку:
Может быть более одного определения
[...]
(13.4) — шаблонная сущность (13.1) ,
[...]
(13.6) — аргумент шаблона по умолчанию
в программе при условии, что каждое определение появляется в отдельной единице перевода и определения удовлетворяют
следующим требованиям. Учитывая, что такой объект D определен более чем в одной единице перевода, для всех определений
D [...] должны быть удовлетворены следующие требования.
[...]
(13.10) — В каждом таком определении, за исключением аргументов по умолчанию и аргументов шаблона по умолчанию для D,
соответствующие лямбда-выражения должны иметь один и тот же тип замыкания (см. ниже).
Теперь мы можем применить этот абзац к приведенному выше фрагменту кода либо
а) приняв D в качестве шаблона класса (который является шаблонной сущностью), и в этом случае (13.10), кажется, говорит Аргумент шаблона по умолчанию исключается из этого правила, или
b) если D является аргументом шаблона по умолчанию, к которому должно применяться это правило. «См. ниже» в конце цитаты относится, я полагаю, к пункту 14:
Если D является шаблоном и определен более чем в одном единицы перевода, то предыдущие требования должны
применяться как к именам из области охвата шаблона, используемой в определении шаблона (13.8.3), так и
к зависимым именам в момент создания экземпляра (13.8.2 ). Эти требования также применяются к соответствующим
объектам, определенным в каждом определении D (включая типы замыкания лямбда-выражений, но исключая
объекты, определенные в аргументах по умолчанию или аргументах шаблона по умолчанию либо D, либо объект, который не определен
в пределах D). Для каждой такой сущности и для самого D поведение такое, как если бы существовала одна сущность с одним
определением, в том числе при применении этих требований к другим сущностям. [Примечание: сущность по-прежнему
объявляется в нескольких единицах перевода, и к этим объявлениям по-прежнему применяется версия 6.6. В частности, лямбда-выражения (7.5.5), появляющиеся в типе D, могут привести к тому, что разные объявления будут иметь разные типы,
а лямбда-выражения, появляющиеся в аргументе D по умолчанию, могут по-прежнему обозначать разные типы в разныхединицы перевода. — конец примечания]
из чего я понимаю: если D — мой класс шаблона, аргумент шаблона по умолчанию освобождается от этого правила. Но затем в примечании в конце указывается, что лямбда-выражение в аргументе шаблона по умолчанию может иметь разные типы в разных TU, следовательно, я полагаю, что это нарушает ODR.
Изменить 2: очень многое связано, но я, похоже, до сих пор не могу прийти к окончательному выводу:
Значение примечания о многократно определенных элементах
Выполнять лямбда-выражения, которые появляются в разных определениях один и тот же объект производит одно и то же замыкание типа?
Подробнее здесь: https://stackoverflow.com/questions/792 ... -defaulted
Мобильная версия