当前位置: 首页 > news >正文

全面理解-c++11的引用折叠

在 C++ 中,引用折叠(Reference Collapsing) 是一组用于处理多重引用(如 T& & 或 T&& &&)的规则,主要出现在模板参数推导、auto 类型推导和 decltype 的上下文中。它是实现**通用引用(Universal Reference)完美转发(Perfect Forwarding)**的关键机制。


引用折叠的规则

C++ 标准规定,当出现多重引用时,编译器会将其折叠为单一引用,规则如下:

多重引用组合折叠后的类型
T& &T&(左值引用)
T& &&T&(左值引用)
T&& &T&(左值引用)
T&& &&T&&(右值引用)

简而言之:

  • 只要存在左值引用(&),最终结果就是左值引用

  • 只有全是右值引用(&&)时,结果才是右值引用


引用折叠的应用场景

1. 模板参数推导与通用引用

在模板参数推导中,T&& 可能被推导为左值引用或右值引用,具体取决于传入的实参:

  • 如果传入左值T 被推导为 T& → T&& 折叠为 T&

  • 如果传入右值T 被推导为 T → T&& 保持为 T&&

这种 T&& 被称为通用引用(Universal Reference)

示例
template<typename T>
void func(T&& arg) { 
    // arg 可能是左值引用或右值引用
}

int main() {
    int x = 10;
    func(x);   // x 是左值 → T 推导为 int& → arg 类型为 int& && → 折叠为 int&
    func(20);  // 20 是右值 → T 推导为 int → arg 类型为 int&&
}

2. auto 类型推导

auto&& 的推导规则与模板参数推导类似,也会发生引用折叠:

int x = 10;
auto&& a = x;   // a 是 int&(左值引用)
auto&& b = 20;  // b 是 int&&(右值引用)

3. typedef 或 using 别名

在类型别名中,引用折叠也会生效:

template<typename T>
using Ref = T&&;

int n = 10;
Ref<int&> r = n;  // Ref<int&> → int& && → 折叠为 int&

4. decltype 类型推导

decltype 的结果可能包含引用,进一步参与折叠:

int x = 10;
decltype((x)) y = x;  // (x) 是左值 → decltype((x)) 是 int&

引用折叠与完美转发

引用折叠是实现**完美转发(Perfect Forwarding)**的核心机制。通过结合 std::forward,可以将参数的值类别(左值/右值)无损地转发给其他函数。

示例
template<typename T>
void wrapper(T&& arg) {
    // 完美转发:保留 arg 的原始值类别(左值/右值)
    target(std::forward<T>(arg));
}

void target(int& x) { std::cout << "左值引用\n"; }
void target(int&& x) { std::cout << "右值引用\n"; }

int main() {
    int x = 10;
    wrapper(x);   // 调用 target(int&)
    wrapper(20);  // 调用 target(int&&)
}
  • std::forward<T>(arg) 的实现依赖于引用折叠:

    template<typename T>
    T&& forward(std::remove_reference_t<T>& t) noexcept {
        return static_cast<T&&>(t);  // 引用折叠在此发生
    }

引用折叠的必要性

在 C++11 引入右值引用之前,引用的引用(如 int& &)是语法错误。为了支持模板和完美转发,C++11 引入了引用折叠规则:

  • 允许在模板推导中隐式生成多重引用。

  • 通过折叠规则解决多重引用的合法性。


总结

场景规则
模板参数推导T&& 可能是左值引用或右值引用(通用引用)
auto&&类似模板推导,支持左值或右值引用
完美转发std::forward 利用引用折叠保留参数值类别
类型别名using 或 typedef 中可能触发引用折叠

引用折叠是 C++11 中实现现代模板编程的关键机制,尤其在通用引用和完美转发中扮演核心角色。理解它可以帮助你更好地掌握移动语义和高效资源管理。

相关文章:

  • PyQt6/PySide6 的 QPropertyAnimation 类
  • Golang GC 三色标记法
  • 多维度健康养生指南
  • 【计算机网络】网络层数据包(Packet)格式
  • 全方位养生指南:打造健康生活蓝图
  • vue-plugin-hiprint (vue2
  • 文本表示方法
  • 什么是FCC认证
  • React echarts柱状图点击某个柱子跳转页面
  • QxOrm生成json
  • Django 创建表时 “__str__ ”方法的使用
  • buu-ciscn_2019_c_1-好久不见36
  • SpringBoot整合Email 邮件发送详解
  • Python经典游戏:植物大战僵尸(附源码!)
  • mac 意外退出移动硬盘后再次插入移动硬盘不显示怎么办
  • springboot整合modbus实现通讯
  • github用户名密码登陆失效了
  • SolidWorks速成教程P3-7【零件 | 第七节】——3D设计打印手机支架+草图文本草图图片材质与质量属性测量
  • TypeScript 面试题
  • 直线导轨尺寸参数
  • 商务部就开展加强战略矿产出口全链条管控工作应询答记者问
  • 古巴外长谴责美国再次将古列为“反恐行动不合作国家”
  • 重庆发布经济犯罪案件接报警电子地图,企业可查询导航属地经侦服务点
  • 央媒评网红质疑胖东来玉石定价暴利:对碰瓷式维权不能姑息
  • 王毅谈中拉命运共同体建设“五大工程”及落实举措
  • 三亚通报救护车省外拉警报器开道旅游:违规违法,责令公司停业整顿