You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于C++20标准中lambda按值捕获*this时‘instead’表述的疑问

C++20草案n4849 §7.5.5.2-11([expr.prim.lambda.capture.6])lambda捕获规则疑惑

我对C++20草案n4849的§7.5.5.2-11(即[expr.prim.lambda.capture.6])中关于lambda表达式复合语句内id-expression指代规则的内容存在疑惑。条款指出:

  1. lambda复合语句中,每个是被按值捕获实体的odr-use的id-expression会被转换为对闭包类型对应无名数据成员的访问;
  2. 非odr-use的id-expression指代原实体,但仍会触发隐式捕获;
  3. 若*this被按值捕获,每个odr-use *this的表达式会被转换为转而指代闭包类型对应无名数据成员。

疑问点

  • 最后一段中的‘instead’为何存在?从语法角度,我认为该段的‘that odr-uses’应被移除,这样‘instead’才能与仅在odr-use时访问数据成员的通用情况形成对比;
  • 另一种解读是‘instead’对应更通用的‘expression’而非‘id-expression’,此时我想了解标准对*this的非odr-use的规定是什么?

解答

关于‘instead’的存在原因

标准文本里的‘instead’是为了明确按值捕获*this与按值捕获普通变量的行为差异:

  • 普通变量按值捕获时,只有当id-expression构成odr-use时,才会被转换为闭包数据成员的访问;
  • 而按值捕获this时,所有构成odr-use的表达式(不限于id-expression,比如this->foo()、(*this).bar()这类表达式中的this)都会被重定向到闭包内的无名数据成员——‘instead’就是强调“原本指向原对象的*this表达式,现在转而指向闭包保存的对象拷贝”,和普通变量的规则形成清晰对比。

你认为‘that odr-uses’应该移除的想法是对规则适用范围的误解:普通变量的规则仅针对id-expression,而this的规则覆盖所有odr-use的表达式,所以‘that odr-uses’是必要的,用来限定只有触发odr-use的this相关表达式才会被转换,‘instead’则明确转换后的指向对象。

关于*this的非odr-use规定

当this被按值捕获但属于非odr-use时,行为和普通变量的非odr-use规则一致:表达式仍然指代原对象,但会触发隐式捕获(如果是通过[=]隐式按值捕获this的话)。

举个代码示例:

struct S {
    int x = 42;
    void f() {
        auto lam = [=] {
            // 非odr-use:仅读取成员值,无需形成原对象的引用,直接指代原对象的x
            int y = x; 
            // odr-use:显式使用*this,被转换为闭包内的*this拷贝,访问拷贝的x
            int z = (*this).x; 
        };
        lam();
    }
};

C++20中,按值捕获this(显式[*this]或隐式[=])会在闭包类型中生成一个无名非静态数据成员,类型为std::decay_t<decltype(*this)>(原对象的拷贝)。非odr-use的this相关表达式不会访问这个拷贝,仍直接关联原对象。


内容的提问来源于stack exchange,提问作者user20575107

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:37:35