为什么编译器不能推导出自动模板参数,除非我添加const?

Gui*_*cot 9 c++ templates language-lawyer argument-deduction c++17

我最近有这样的代码问题:

constexpr auto lambda = []{};

template<auto& l>
struct Lambda {};

template<auto& l>
void test(Lambda<l>) {}

int main() {
    test(Lambda<lambda>{});
}
Run Code Online (Sandbox Code Playgroud)

clang和GCC都说不能推断l.

但是,如果我在那里添加const:

//   ----v
template<const auto& l>
void test(Lambda<l>) {}
Run Code Online (Sandbox Code Playgroud)

然后一切都与clang一起工作.GCC仍然失败.这里发生了什么事?难道它不能推断const自己吗?这是否是GCC的错误,l在两种情况下都没有推断?

Sto*_*ica 8

这是否是一个GCC错误,它在两种情况下都没有推断出l?

这是一个bug,对于Clang来说也是如此.对于占位符类型的非类型参数,[temp.arg.nontype]/1表示:

如果template-parameter的类型包含占位符类型,则推导出的参数类型由占位符类型推导的template-argument类型确定.如果模板参数声明([temp.param])不允许使用推导出的参数类型,则程序格式错误.

它在这里演绎的过程非常相同

int main() {
   auto& l = lambda;
}
Run Code Online (Sandbox Code Playgroud)

l是const参考.