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

C++20中丢弃值表达式与odr-used疑问:未捕获局部变量为何报错

C++20 Lambda未捕获局部变量报错的原因解析

先看你的示例代码:

#include <iostream>
using namespace std;

int main() {
     int n=1;
    []()
        {
            n;// (1): 错误
         }();
}

你对odr-used规则的理解是对的:这里单独的n是丢弃值表达式,且没有触发左值到右值转换,所以n确实没有被odr-used。但代码报错的核心原因,是你忽略了C++20中lambda捕获的补充规则:

关键规则补充

C++20标准中,lambda表达式对外部局部实体的使用,除了odr-used的场景外,还有一条要求:

如果局部实体在lambda的潜在求值表达式中被命名(且不属于未求值操作数,比如sizeof的参数),即使它没有被odr-used,也必须被捕获——要么显式写出捕获列表,要么通过捕获默认值([=]或[&])隐式捕获。

代码错误的具体原因

你的lambda既没有显式捕获n,也没有设置捕获默认值,完全没有满足对n的捕获要求,因此编译器会报错。

再结合你引用的odr-usable规则来看:n在lambda的块作用域中属于非odr-usable状态——因为lambda的参数作用域作为中间声明区域,既不是块作用域,lambda也没有捕获n或设置捕获默认值。不过这个规则的触发条件是“在非odr-usable区域中odr-used”,而你代码的错误本质是违反了lambda的捕获规则,和odr-usable的直接关联不大。

修复方案

要让代码合法,有两种简单方式:

  • 显式捕获n:
    [n](){ n; }();
    
  • 使用捕获默认值(按值或按引用):
    [=](){ n; }(); // 按值捕获
    // 或者
    [&](){ n; }(); // 按引用捕获
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:17:06