Ссылка на конкретную специализацию шаблона из неинстанцированного контекста: инстанцирование или нет? - PullRequest
0 голосов
/ 08 декабря 2018

Рассмотрим следующий пример.

template <typename A> struct S 
{
  A a;
  void foo() {}
};  

template <typename T> void bar()
{
  S<void> *p = 0;
}

template <typename T> void baz()
{
  S<void>{}.foo();
}

template <typename T> void qux()
{
  S<void> s{};
}

int main()
{
}

Шаблоны функций bar, baz и qux намеренно оставлены неинстанцированными.

Определение baz не удаетсякомпилировать в GCC и Clang по «очевидной» причине - S<void> является недопустимой специализацией S.Однако какое правило языка работает в этом случае?

  1. С одной стороны, S<void> не зависит от параметров шаблона baz, доступ к элементу требует его завершения,который запускает создание экземпляра S<void>, что не удается.Диагностика обязательна.

  2. С другой стороны, у нас есть общее правило: «Если не может быть сгенерирована действительная специализация для неинстанцированного шаблона, код некорректно сформирован».Это делает определение baz плохо сформированным.Тем не менее, никакой диагностики не требуется.

В частности, правильно ли я в своем предположении (как выражено в # 1), что приведенная выше ссылка на S<void> от неинстанцированного bazтребует создания экземпляра S<void>?Предположение подтверждается тем фактом, что оба компилятора с радостью принимают определение bar, которое не создает экземпляр S<void>.

Однако вышеупомянутые компиляторы по-разному трактуют qux - Кланг жалуется,в то время как GCC принимает это без каких-либо жалоб.Это ошибка в одном из компиляторов?Требуется ли в этом случае диагностика?Или я ошибаюсь, полагая, что № 1 здесь на работе?Если № 2 является основой для диагностики, то разница между компиляторами является приемлемой.

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

И S<void>{}, и S<void> s{} используются в контексте, который требует создания экземпляра S<void>, такой экземпляр плохо сформирован из-за члена, имеющего неполный тип void.

Соответствующие кавычки: [temp.inst]/1:

Если специализация шаблона класса не была явно создана или явно специализирована, специализация шаблона класса создается неявно, когда на специализацию ссылаются вконтекст, который требует полностью определенного типа объекта или когда полнота типа класса влияет на семантику программы.[...]

и [temp.arg]/6:

Если использование аргумента шаблона приводит к неправильной конструкции конструкции в экземпляре шаблонаспециализация, программа плохо сформирована.

С другой стороны, baz и quz плохо сформированы NDR [temp.res]/8:

Знание того, какие имена являются именами типов, позволяет проверять синтаксис каждого шаблона.Программа некорректна, диагностика не требуется, если:

(8.1) для шаблона не может быть сформирована действительная специализация , [...]

0 голосов
/ 08 декабря 2018

Как для baz, так и qux, допустимость выражения, включающего S<void>, может быть выполнена только через экземпляр S. Тем не менее, компиляторы не обязаны выполнять эту проверку перед любой реализацией [temp.res] / 8

Срок действия шаблона может быть проверен перед выполнением любого экземпляра.[...] Программа некорректна, диагностика не требуется, если:

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