Ошибка в шаблоне псевдонима MSVC? - PullRequest
3 голосов
/ 20 сентября 2019

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

Следующий код выдает ошибки о необъявленных идентификаторах и недопустимых аргументах по умолчанию:

template <class T>
struct dummy_struct {};
template <class T>
using dummy_alias = dummy_struct<T>;

template <template <class> class Thing>
struct foo {
    template <template <class> class T = Thing>
    void bar() {}
};

int main() {
    foo<dummy_alias> fdsa;
    fdsa.bar();
}
error C3202: 'Thing': invalid default argument, expected a class template
note: see reference to class template instantiation 'foo<dummy_alias>' being compiled
error C2065: 'Thing': undeclared identifier

Вот ссылка на Compiler Explorer для приведенного выше примера: https://godbolt.org/z/e2SEpD

Корень проблемы, по-видимому, в том, что MSVC неудобно из-за того, что шаблоны псевдонимов используются в качестве параметров шаблона шаблона.

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

Для пояснения этот код без проблем компилируется в последних версиях gcc, clang и icc.

1 Ответ

1 голос
/ 20 сентября 2019

При строгом прочтении Стандарта, программа некорректна, поэтому gcc и clang ошибаются в том, что не печатают диагностику.

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

[temp.param] / 3 говорит

A параметр типа , чей идентификатор делаетне следовать многоточию определяет его идентификатор как typedef-имя (если объявлено без template) или имя-шаблона (если объявлено с template) в области объявления шаблона.

Таким образом, параметр шаблона шаблона, такой как Thing, представляет собой имя-шаблона , что делает допустимым написание простого -template-id как Thing<int>.

Но [temp.arg.template] / 1 говорит

A template-аргумент для шаблона template-параметр должен быть именем шаблона класса или шаблона псевдонима, выраженным как id-выражение .

(Технически аргумент шаблона по умолчанию не является синтаксически аргументом шаблона , так как синтаксическое дерево параметра *1049* не используетнетерминальный шаблон-аргумент после токена = вместо непосредственного использования type-id и id-expression .Однако [temp.param] / 11 связывает их, поскольку идентификатор типа или id-выражение может быть проанализирован как template-аргумент : "по умолчанию шаблон-аргумент представляет собой шаблон-аргумент ([temp.arg]), указанный после = в шаблон-параметра . ")

Здесь Thing определенно не является именем шаблона класса, и ничто не говорит, что это имя шаблона псевдонима, просто template-name .

...