Лямбда в параметре шаблона по умолчанию считается частью непосредственного контекста? - PullRequest
0 голосов
/ 03 декабря 2018

Является ли следующий код правильно сформированным C ++ 17?

template <typename T, int = [](auto t) { decltype(t)::invalid; return 0; }(T{})>
constexpr int f(T) { return 0; }
constexpr int f(...) { return 1; }

static_assert(f(0) == 1);

clang и edg принимают его, в то время как msvc и gcc 1 отклоняют его.Я не могу найти ничего, что говорило бы, что это серьезная ошибка, но я также не могу найти ничего, что говорило бы, что это ошибка вычета.

В C ++ 20 есть этот параграф( [temp.deduct] p9 ):

A лямбда-выражение , появляющееся в типе функции или параметре шаблона, не считается частью непосредственногоконтекст для целей вывода аргумента шаблона.

, который проясняет, что лямбда не является частью непосредственного контекста.Но как насчет C ++ 17?


1 : в этом контексте у gcc есть ошибка с auto, но перезапись ее с использованием явных параметров шаблона для лямбды дает вамта же ошибка.

1 Ответ

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

В C ++ 17, если я правильно понял, все плохо.

[expr.prim.lambda] (выделено мной)

2 Лямбда-выражение не должно появляться в неоцененном операнде, в аргументе шаблона , [...]

[temp.param] (выделено мной)

9 Аргумент шаблона по умолчанию - это аргумент шаблона ([temp.arg]), указанный после = в шаблоне-параметр.

В обоих случаях «шаблон-аргумент» является одним и тем же нормативным термином.Поэтому я считаю, что Clang и edg err принимают код в OP как действительный C ++ 17.

...