我能在模板参数中声明constexpr lambda吗?

W.F*_*.F. 19 c++ templates language-lawyer c++17

我知道这就像打开潘多拉盒子一样,但它并没有停止打扰我.考虑一个简单的例子:

#include <type_traits>

template <auto>
struct Foo: std::false_type { };

template <>
struct Foo<[](){return 1;}()>:std::true_type { };

int main() {
    static_assert(Foo<1>::value);
}
Run Code Online (Sandbox Code Playgroud)

我知道lambdas不能在未评估的上下文中声明,但显然这不是这里的情况.什么是更奇怪的clang 5.0.0(我猜,首先部分支持constexpr lambda)确实编译它.

它是编译器错误还是C++ 17允许这样做?

Rak*_*111 25

不,这是一个编译器错误.gcc 7.1正确拒绝代码.

[expr.prim.lambda]/2:

lambda-expression是一个prvalue,其结果对象称为闭包对象.lambda表达式不应出现在未评估的操作数,模板参数,别名声明,typedef声明或函数体和默认参数之外的函数或函数模板的声明中.

从我标记为粗体的部分可以看出,lambda表达式不能出现在模板参数列表中.

在随后的说明中也明确了这一点:

[注意:目的是防止lambda出现在签名中. - 结束说明]

如果我猜测,我会说这个错误是因为从C++ 17开始,lambdas是隐式的constexpr,这使得它们在编译时表达式(如模板参数)中被调用.但实际上在模板参数中定义lambda仍然是非法的.


请注意,此限制已在C++ 20中解除.:)

  • @DanielJour不,对不起.但这会使元编程甚至*更令人困惑:) (3认同)