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

如何理解C++模板函数中左值(lvalues)与右值(rvalues)的处理?附示例

C++模板函数中的左值(lvalues)与右值(rvalues)详解及std::forward示例分析

嘿,咱们来好好唠唠C++里左值右值和std::forward那点事儿——这玩意儿刚接触的时候确实容易懵,不过拆开来就清晰多了!

一、左值与右值的核心概念

  • 左值(lvalue):简单说就是你能拿&取地址的对象,它有持久的内存位置,能出现在赋值号左边。比如你定义的变量int a = 5;,a就是左值,你可以写a = 10;,也能做&a取地址操作。
  • 右值(rvalue):临时的、用完就销毁的对象,没法取地址,只能出现在赋值号右边。比如字面量5、表达式a+b的计算结果,或者被std::move()处理过的"将亡值"都属于右值——你没法写5 = a;,也不能对a+b取地址。

二、模板中的"万能引用"(T&&)

模板参数里的T&&可不是普通的右值引用,江湖人称万能引用(也叫转发引用),它会根据传入的实参自动推导类型:

  • 如果传入左值,T会被推导为左值引用类型,经过C++的"引用折叠"规则,T&&最终变成左值引用(比如int& &&折叠为int&);
  • 如果传入右值,T会被推导为非引用类型,此时T&&就是标准的右值引用。

这玩意儿是实现"完美转发"的基础,而std::forward就是用来干这件事的工具。

三、std::forward示例代码拆解

先把示例代码完整贴出来:

// forward示例
#include <utility>  // std::forward
#include <iostream> // std::cout

// 包含左值引用和右值引用重载的函数:
void overloaded (const int& x) {std::cout << "[lvalue]";}
void overloaded (int&& x) {std::cout << "[rvalue]";}

// 接收推导类型右值引用的函数模板:
template <class T>
void fn (T&& x) {
  overloaded (x); // 不管传入啥,这里x都是左值
  overloaded (std::forward<T>(x)); // 转发x的原始值类别
}

int main () {
  int a = 10;
  std::cout << "calling fn(a): ";
  fn(a); // 传入左值
  std::cout << '\n';

  std::cout << "calling fn(10): ";
  fn(10); // 传入右值
  std::cout << '\n';

  return 0;
}

代码逐行分析

  1. 重载的overloaded函数:两个版本分别对应左值和右值参数,调用时会输出对应的标记,用来直观显示当前触发的是哪个版本。
  2. 模板函数fn:
    • 第一行overloaded(x);:不管你传入的是左值还是右值,只要变量有名字(这里x是有名字的局部变量),它在函数内部就是左值!所以这行代码永远会调用左值版本的overloaded,输出[lvalue]。
    • 第二行overloaded(std::forward<T>(x));:这就是std::forward的核心作用——完美转发。它会根据模板参数T的推导结果,把x转换成它最初的类型:
      • 当传入左值a时,T被推导为int&,std::forward<int&>(x)会把x转换成左值引用,继续调用左值版本,输出[lvalue];
      • 当传入右值10时,T被推导为int,std::forward<int>(x)会把x转换成右值引用,触发右值版本的overloaded,输出[rvalue]。

运行结果及解释

程序运行后会输出:

calling fn(a): [lvalue][lvalue]
calling fn(10): [lvalue][rvalue]

完全符合咱们的分析:调用fn(a)时两行都是左值调用;调用fn(10)时,第一行因为x是有名字的左值触发左值版本,第二行通过std::forward转发了原始右值类型,触发右值版本。

内容的提问来源于stack exchange,提问作者J. S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:36:36