【发布时间】:2019-04-25 11:32:45
【问题描述】:
根据[this Q&A],因为 c++11 逗号运算符支持 constexpr。根据[this Q&A] constexpr 变量不应该被 lambda 捕获,但应该可以在其体内使用。
这两条规则都使得以下代码可以在 clang 中编译:
//Example 1
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
static_cast<void>(Foo<(c, 2)>{});
}
//Example 2
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
auto lambda = []{return c * 2;};
static_cast<void>(Foo<lambda()>{});
}
然而,虽然这两个示例都在 clang 上成功编译(声明 constexpr lambda 支持,即 8.0.0),但以下 sn-p 没有,我无法想象为什么......有什么想法吗?
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
auto lambda = []{return (c, 2);};
static_cast<void>(Foo<lambda()>{});
}
编译错误:
在未指定捕获默认值的 lambda 中无法隐式捕获变量“c”
【问题讨论】:
-
不是答案,但是......在 wandbox clang++ 中抱怨,因为“变量 'c' 无法在未指定捕获默认值的 lambda 中隐式捕获”;通过引用捕获 (
[&]) 抱怨,因为“对 'c' 的引用不是常量表达式”;按值捕获 ([=]) 编译没有问题。有趣的是,g++ 在所有三种情况下都可以毫无问题地编译。 -
我认为逗号操作符引用了c,并且引用break constexpr
-
clang 错误?我不是语言层,所以坦率地说,我不知道。
-
但完美运行
constexpr auto lambda = []{ auto a=c; return a;};;所以c值没有问题,但是当c被视为对c的引用时出错? -
只需在 bugs.llvm.org 上记录一个错误,因为它不同,一个答案似乎表明 GCC 是正确的
标签: c++ lambda language-lawyer c++17 constexpr