gpt4 book ai didi

c++ - 在模板 lambda 中隐式捕获 const 变量,而未指定捕获默认值

转载 作者:行者123 更新时间:2023-12-04 11:11:11 25 4
gpt4 key购买 nike

考虑以下代码:

auto f() {
const auto x = 1;
return [] (auto) { return x; };
}
GCC and MSVC compiles fine but Clang rejected it .我应该信任哪个编译器?那是 Clang 尚未实现的编译器扩展还是只是 Clang 错误?

最佳答案

这是一个 clang 错误。
我们的规则是 [basic.def.odr]/9 :

A local entity is odr-usable in a scope if:

  • either the local entity is not *this, or an enclosing class or non-lambda function parameter scope exists and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member function, and
  • for each intervening scope ([basic.scope.scope]) between the point at which the entity is introduced and the scope (where *this is considered to be introduced within the innermost enclosing class or non-lambda function definition scope), either:
    • the intervening scope is a block scope, or
    • the intervening scope is the function parameter scope of a lambda-expression that has a simple-capture naming the entity or has a capture-default, and the block scope of the lambda-expression is also an intervening scope.

If a local entity is odr-used in a scope in which it is not odr-usable, the program is ill-formed.


在我们的例子中:
auto f() {
const auto x = 1;
return [] (auto) { return x; };
}
x由于不捕获 x 的介入范围,因此无法在 lambda 主体中使用 odr (既不是简单捕获也不是默认捕获)。
所以,它不是 odr 可用的。但它是 odr 使用的吗?不,来自 [basic.def.odr]/4 :

A variable is named by an expression if the expression is an id-expression that denotes it. A variable x whose name appears as a potentially-evaluated expression E is odr-used by E unless

  • x is a reference that is usable in constant expressions ([expr.const]), or
  • x is a variable of non-reference type that is usable in constant expressions and has no mutable subobjects, and E is an element of the set of potential results of an expression of non-volatile-qualified non-class type to which the lvalue-to-rvalue conversion ([conv.lval]) is applied, or
  • x is a variable of non-reference type, and E is an element of the set of potential results of a discarded-value expression ([expr.prop]) to which the lvalue-to-rvalue conversion is not applied.

第二个要点适用(我们的变量甚至被命名为 x !) x可用于常量表达式,因为它是常量整数类型和 E这里是左值到右值的转换。
所以 x不是 odr-usable,也不是 odr-used,所以这里没有问题。

事实上,我们甚至在 [expr.prim.lambda.capture]/7 中有这个例子。 :
void f(int, const int (&)[2] = {});         // #1
void f(const int&, const int (&)[1]); // #2
void test() {
const int x = 17;
auto g = [](auto a) {
f(x); // OK: calls #1, does not capture x
};
}

关于c++ - 在模板 lambda 中隐式捕获 const 变量,而未指定捕获默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66456916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com