【发布时间】:2018-05-09 07:31:06
【问题描述】:
这个问题Access to constexpr variable inside lambda expression without capturing 回答了为什么下面示例中的 ref-capture 不是绝对必要的。但另一方面,如果它被捕获,则会出现错误。
错误似乎是由foo() 的递归性质触发的。
template<typename T>
constexpr int bar(const T& x) { // NOK
//constexpr int bar(T x) { // OK
return x;
}
template<typename T>
int foo(const T& l) {
constexpr auto x = l() - 1;
auto y = [&]{return bar(x);}; // if ref-capture is used, the above bar(const T&) is NOK, why?
if constexpr(x <= 0) {
return 42;
}
else {
return foo(y);
}
}
auto l2 = []{
return 3;
};
int main() {
foo(l2);
}
【问题讨论】:
-
如果你在捕获组中放入任何东西(
[x],[&x],[&],...),它实际上会发生,它与y不是@987654328有关@ 在某些时候不再存在,所以l() - 1不是编译时表达式并且编译失败。 -
使用clang,这两种方式都会产生错误,这对我来说更有意义。我不明白为什么 GCC 在这种情况下认为
l() - 1是一个常量表达式。 -
这听起来很奇怪,因为
l() - 1应该真的是constexpr。 -
我认为 clang++ 在这里是错误的。您可以测试,
l() - 1在main()中给出带有以下行的 constexpr:constexpr auto z = l2() - 1; -
@wimalopaan 当
foo<decltype(l2)>被实例化时,参数l是一个没有用常量表达式初始化的引用。未使用常量表达式初始化的引用不能在常量表达式中使用。
标签: c++ lambda language-lawyer c++17