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

C++23中能否实现保留纯右值的完美转发?

实现保留纯右值的完美转发(C++)

需求与现有问题

我们需要构造一个FORWARD(e)表达式,满足以下核心要求:

  • FORWARD(e)与e的类型相同(忽略限定符)
  • 若decltype(e)是左值/右值引用,则FORWARD(e)分别对应左值/亡值
  • 若decltype(e)不是引用类型,FORWARD(e)与e的值类别完全一致
  • 不会产生额外的复制或移动开销

目前基于std::forward的常见实现存在缺陷:

#define FORWARD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)

它能正确处理引用类型,但会把纯右值转为亡值——因为std::forward对非引用类型的decltype(e)会返回右值引用,导致原本可以触发复制省略的场景被迫调用移动构造:

T x = T();          // 纯右值初始化,触发复制省略
T x = FORWARD(T()); // 转为亡值,调用移动构造函数

解决方案

C++23:实现完美转发(含纯右值保留)

C++23引入的decltype(auto)配合静态转换,可以直接实现完全符合要求的转发:

#define FORWARD(...) static_cast<decltype(auto)>(__VA_ARGS__)

场景验证:

  1. 左值引用:当decltype(e)为T&时,static_cast<decltype(auto)>(e)返回左值,符合要求
  2. 右值引用:当decltype(e)为T&&时,返回亡值,符合转发规则
  3. 纯右值:当decltype(e)为T时,static_cast会保留其纯右值属性,此时T x = FORWARD(T())可以正常触发复制省略,不会调用移动构造
  4. 无额外开销:static_cast是编译期转换,不会产生任何运行时复制或移动操作

C++23之前的限制

在C++20及更早版本中,语法层面无法区分纯右值和亡值(两者同属右值范畴),也没有手段在表达式层面保留纯右值的原始属性。因此无法实现完全满足所有要求的通用FORWARD(e),只能接受std::forward带来的纯右值转亡值的行为,或针对特定场景做定制化处理,但无法覆盖所有情况。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:22:12