作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这个问题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);
}
最佳答案
如果我们使用 clang 作为编译器,当谈到语言律师时,它通常比 gcc 更相关,我们发现一个简化的例子非常有说服力:
template<typename T>
int foo(T/*&*/ l) {
constexpr auto x = l() - 1;
if constexpr(x <= 0) {
return 42;
}
else {
return 0;
}
}
auto l2 = []{
return 3;
};
int main() {
foo(l2);
}
在foo()
签名中添加和删除引用可以使程序编译或不编译。我相信,这与关于 cppreference 的常量表达式主题的第 12 条有关:
an id-expression referring to a variable or a data member of reference type, unless it was initialized with a constant expression or its lifetime began within the evaluation of this expression
https://en.cppreference.com/w/cpp/language/constant_expression
所以这两个语句似乎都不满足,因为引用不是用常量表达式初始化的,而且它的生命周期不是从表达式求值开始的。
关于c++ - lambda 表达式中引用捕获和非显式捕获的 constexpr 变量之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50247850/
我是一名优秀的程序员,十分优秀!