使用lambda中捕获的常量值作为模板参数合法吗

Is it legal to use a const value captured in a lambda as a template argument?

本文关键字:参数 lambda 常量 使用      更新时间:2023-10-16

考虑一下同事提供的以下代码:

#include <array>
#include <string>
int main() {
const int size = 4;
return [size]() {
std::array<std::string, size> a; // *
return a.size();
}();
}

Clang 5.0.0接受了它,但GCC 7.2拒绝了它,星型线的错误消息是:

error: '__closure' is not a constant expression

哪个编译器是对的?

规则实际上是直观的:任何不需要捕获的变量都会引用原始变量。[expr.prim.lambda]/11:

lambda表达式是复制捕获的实体的odr使用转换为对的相应未命名数据成员的访问闭合类型。[注意:不是odr使用的id表达式引用原始实体,而不是闭包类型的成员。[…]--尾注]

很明显,声明的size变量可以在常量表达式中使用,因此Clang是对的。