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

当移动赋值被删除时,拷贝赋值如何处理右值?

问题分析与解答

代码片段

struct S
{
  S() = default(); 
  S(S const&){std::cout << "copy ctor" << '\n';};
  S& operator=(S const&) { std::cout << "copy assignment" << '\n'; return *this; }
  ~S();
};

S createS(){return S{};} // 注:原代码中`return s{}`应为笔误,修正为`return S{}`

int main()
{
  S s{}; 

  s = createS(); 
}

1. main()中赋值操作的实际行为

执行s = createS();时,会调用拷贝赋值运算符,控制台会输出copy assignment。

具体逻辑:

  • createS()返回的是右值,但我们没有为S定义移动赋值运算符(operator=(S&&))。
  • 根据C++规则:当类显式声明了拷贝构造、拷贝赋值、析构中的任意一个,编译器不会自动生成移动构造和移动赋值运算符,且这些移动操作会被隐式删除。
  • 此时编译器会寻找可匹配右值的赋值运算符,而operator=(const S&)的参数是const左值引用——C++标准允许右值绑定到const左值引用,因此该拷贝赋值运算符会被选中执行。

2. 右值与左值的绑定逻辑

const左值引用是C++标准特意设计的“可兼容右值的引用类型”,它既可以绑定左值,也可以绑定右值。

从语义上看,拷贝操作仅需要读取被拷贝对象的值,右值虽然无法被修改、复用,但它的值是可读的;const左值引用恰好保证了不会修改引用对象,因此绑定右值完全合法。

如果想让右值触发移动而非拷贝,只需显式定义移动赋值运算符:

S& operator=(S&&) noexcept { std::cout << "move assignment" << '\n'; return *this; }

此时createS()返回的右值会优先匹配移动赋值运算符。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:13:11