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

C++类型擦除场景下模板类拷贝构造函数未触发问题求助

问题根因

你遇到的现象是C++万能引用的类型推导规则+引用折叠共同作用的结果,具体推导过程如下:

  1. 执行Object obj2(a2)时,a2是左值,匹配Object的模板构造函数的万能引用参数T&& obj:
    • 按照万能引用的推导规则,传入左值时模板参数T会被推导为左值引用类型A&
    • 结合引用折叠规则,T&&即A& &&会折叠为A&,最终构造函数的形参就是A&类型,完美匹配传入的左值a2
  2. 构造Model实例时用的模板参数是推导出来的T = A&,因此实例化的是Model<A&>类:
    • 该类的成员变量T obj_实际是A&类型,也就是左值引用,而非A类型的实例
    • Model构造函数的形参T&& obj同样会折叠为A&,初始化obj_(std::forward<T>(obj))的本质是把形参引用绑定到成员引用,完全不需要调用A的拷贝构造函数
  3. 所以你运行时看到三个地址完全一致,都是栈上a2本身的地址,也没有拷贝构造的日志输出,完全符合代码逻辑。

修复方案

如果你的预期是Model内存储擦除类型的独立实例,而非引用外部变量,需要在实例化Model时去掉T的引用、cv等限定符,用std::decay处理模板参数即可:
把Object构造函数的初始化列表修改为:

object_(std::make_shared<Model<typename std::decay<T>::type>>(std::forward<T>(obj)))

(gcc4.8还不支持C++14的std::decay_t别名,所以用typename std::decay<T>::type写法即可)
修改后再运行测试用例2,T被decay处理为纯类型A,Model<A>的成员是A类型实例,初始化时就会触发你预期的A的拷贝构造函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:09:02