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

std::pair配合const std::unique_ptr使用时报无匹配函数调用错误

问题根本原因

你遇到的现象是C++类特殊成员函数的隐式生成规则、std::unique_ptr的不可拷贝特性、拷贝消除规则三者共同作用的结果。

前置基础规则

  • std::unique_ptr是独占型智能指针,仅支持移动语义,无拷贝构造/拷贝赋值函数。
  • C++标准规定:若用户显式声明了析构函数(哪怕是=default实现,也算用户声明),编译器将不会隐式生成移动构造函数和移动赋值运算符。
  • 若类包含不可拷贝的非静态成员,编译器隐式生成的拷贝构造/拷贝赋值运算符会被定义为弃置(deleted)。
  • 若类的非静态成员是const修饰的可移动类型,移动构造函数也无法正常生成(移动操作需要修改源对象的成员,const修饰后无法修改。
  • C++17起强制要求纯右值的拷贝消除:当用临时对象初始化同类型对象时,直接在目标对象地址构造,无需调用拷贝/移动构造函数。

各场景编译结果解释

(4)行始终编译正常

代码:TestClass myTestClass = TestClass("myTestClass");
这行触发了强制拷贝消除,不需要调用TestClass的拷贝/移动构造函数,直接在myTestClass的内存地址构造对象,所以不管TestClass是否支持拷贝/移动都不影响编译。

(5)行始终编译失败

代码:std::make_pair("myTestClassKey", myTestClass);
myTestClass是左值,要将其存入std::pair必须调用拷贝构造,或是显式通过std::move转为右值触发移动构造:

  1. 你的TestClass包含std::unique_ptr成员,拷贝构造函数被默认弃置,无法拷贝;
  2. 左值不会自动触发移动语义,std::make_pair尝试调用拷贝构造失败,因此所有场景下都无法编译。

如果要让这行可编译,可修改为:

std::make_pair("myTestClassKey", std::move(myTestClass));

(6)行仅在注释(1)行、使用(2)行时可编译

代码:std::make_pair("myTestClassKey", TestClass("myTestClass"));
这里传入的TestClass是临时右值,std::make_pair会尝试调用移动构造将对象存入pair:

  1. 保留(1)行时:你显式声明了析构函数,编译器不隐式生成移动构造,无可用的拷贝/移动构造,编译失败。
  2. 使用(3)行时:成员是const std::unique_ptr,移动构造需要修改源对象的str成员,const修饰后无法修改,移动构造无法生成,编译失败。
  3. 只有注释(1)行、使用(2)行时:编译器会隐式生成可用的移动构造函数,右值可以触发移动构造,因此编译正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:48:04