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

C++返回右值引用类型的函数返回值是左值还是右值?

关于返回右值引用的函数调用表达式的值类别结论

第二个fun()的返回值确实属于右值,更准确的分类是xvalue(将亡值),属于右值大类,你的测试结果完全符合C++标准的值类别判定规则。


核心判定逻辑

你混淆了两个适用场景不同的值类别规则:

  • 函数调用表达式的值类别,只和函数的返回类型直接相关,和引用绑定的目标无关
    • 当函数返回类型是左值引用T&时,函数调用表达式fun()是左值,这也是你第一个测试返回true的原因
    • 当函数返回类型是右值引用T&&时,函数调用表达式fun()是xvalue(将亡值),归属于右值大类,不会被判定为左值
      这个判定和你return的对象是全局变量、局部变量,还是move转换的结果没有任何关系,只看函数签名的返回类型。
  • 你提到的「声明为右值引用的变量本身也是左值」这个规则是正确的,但它仅适用于有名字的右值引用变量,不适用于函数返回的无名右值引用结果。

举个对比例子:

int x = 9;
int&& rref_var = std::move(x);
// rref_var是有名字的右值引用变量,表达式rref_var是左值
is_lvalue(rref_var); // 返回true

int&& fun() { return std::move(x); }
// fun()是返回右值引用的函数调用表达式,没有名字,属于xvalue(右值)
is_lvalue(fun()); // 返回false

对你的检测工具的补充说明

你写的is_lvalue是基于转发引用的模板推导规则实现的:

  • 传入左值实参时,模板参数T会被推导为左值引用类型,std::is_lvalue_reference<T>判定为true
  • 传入右值(包括prvalue纯右值、xvalue将亡值)实参时,模板参数T会被推导为非引用类型,判定结果为false
    所以你的测试结果是完全准确的。

注意:不要因为fun()返回的右值引用绑定到了全局变量x(有确定内存地址、生命周期长),就误认为这个表达式是左值。C++表达式的值类别是编译期静态属性,和表达式底层绑定对象的存储位置、生命周期没有关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 00:21:40