未捕获 constexpr 变量

constexpr variable not captured

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

struct A{
    int a;
};

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

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

如果 x 是一个整数,代码编译:

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

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

auto test(){
    constexpr A x{10};
    return []{
        return x.a;
    }();
}

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

--编辑--

下面的问题: 与这个无关,因为 clang11 它不再是一个问题:事实上,如上所述,如果 x 是一个 int,clang11 编译。

示例代码也出现在 https://godbolt.org/z/rxcYjz

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

作为一个实际问题,您当然可以创建任何 constexpr 变量 static 以避免任何捕获它的需要。