未捕获 constexpr 变量

Mar*_*ddu 8 c++ lambda constexpr clang++ c++17

以下代码不能在 clang 中编译(在 GCC 中可以):

struct A{
    int a;
};

auto test(){
    constexpr A x{10};
    return []{
        return x; // <-- here x is A: clang doesn't compile
    }();
}
Run Code Online (Sandbox Code Playgroud)

Clang 的错误是变量 'x' 不能在没有指定捕获默认值的 lambda 中隐式捕获,但我认为 constexpr 变量总是被捕获。

如果 x 是 int,则代码编译:

auto test(){
    constexpr int x{10};
    return []{
        return x; // <-- here x is int: clang is ok
    }();
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,以下代码也可以编译:

auto test(){
    constexpr A x{10};
    return []{
        return x.a;
    }();
}
Run Code Online (Sandbox Code Playgroud)

叮当正确吗?如果是这样,理由是什么?我正在使用 -std=c++17

- 编辑 -

以下问题: 我可以在 lambda 中使用 constexpr 值而不捕获它吗? 与此无关,与 clang11 一样,它不再是问题:事实上,如上所述,如果 x 是 int,clang11 会编译。

示例代码也存在于https://godbolt.org/z/rxcYjz

Dav*_*ing 4

当您return x;在第一个示例中时,您必须调用A\xe2\x80\x99s 复制构造函数,这涉及绑定引用x因此 odr 使用它。可以认为,常量表达式中可用的值的简单副本应该\xe2\x80\x99t 构成 odr-use return x.a;,但在该规则中\xe2\x80\x99s 没有这样的例外,所以 Clang 是正确的拒绝它是

\n

实际上,您当然可以创建任何constexpr变量static以避免捕获它。

\n