【发布时间】:2017-02-09 02:17:12
【问题描述】:
Lambda 表达式不允许在未计算的上下文中(例如在 decltype 中),并且直到最近才可以是常量表达式。因此无法在模板参数中使用它们。
然而,在 C++17 中,常量表达式 lambdas 是可能的。这仍然不允许在一般模板参数中使用它们。
但是,对于非类型模板参数,常量表达式 lambda 表达式可以在评估上下文中使用,例如:
template<int N> struct S { constexpr static int value = N; };
int main() {
int N = S<[]()constexpr{return 42;}()>::value;
}
但这仍然行不通,因为无论是类型还是非类型,模板参数中都明确禁止 lambda 表达式。
我的问题是不允许上面的构造背后的原因。我可以理解函数签名中的 lambda 类型可能有问题,但是这里闭包类型本身是无关紧要的,只使用(编译时常量)返回值。
我怀疑原因是 lambda 主体中的所有语句都将成为模板参数表达式的一部分,因此如果主体中的任何语句在替换期间格式不正确,则需要应用 SFINAE。这可能需要编译器开发人员的大量工作。
但这实际上是我的动力。如果可以使用上面的构造,那么 SFINAE 不仅可以用于常量表达式,还可以用于 constexpr 函数中有效的其他语句(例如文字类型声明)。
除了对编译器编写者的影响之外,这是否会导致任何问题,例如标准中的歧义、矛盾或复杂性?
【问题讨论】:
-
我想你已经回答了你自己的问题。
-
好吧,+1 @Barry,这实际上是一个有趣的问答。
-
@Barry 我稍微修改了我的问题。我希望得到一些验证,这确实是(唯一的)主要原因,也许是参考委员会文件/讨论中提到的推理。
-
“如果正文中的任何语句在替换期间格式不正确,则需要应用 SFINAE” 我不确定这是否是一个问题 - SFINAE 仅在直接上下文,并且可以想象将 lambda 的主体解释为不是直接的。
-
constexpr auto f=[]()constexpr{return 42;};在上一行然后调用f()使您的论点没有意义。
标签: c++ templates lambda sfinae c++17