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

C++17中删除移动赋值后,Vector类拷贝赋值未被调用的原因?

为什么拷贝赋值运算符没被调用?

先搞懂:初始化和赋值是两回事

你写的Vector u = w + r;是拷贝初始化,不是赋值操作。赋值运算符operator=只有在给已经存在的对象赋值时才会触发,比如先创建u再给它赋值:

Vector u; // 先默认构造出u
u = w + r; // 这一步才会调用拷贝赋值(因为移动赋值被删了)

而初始化里的=只是语法上的写法,本质是用右边的临时对象构造新的u,和赋值半毛钱关系都没有,自然不会调用赋值运算符。

C++17的强制复制消除让拷贝构造也被跳过

就算你删了移动构造,逻辑上operator+返回的临时对象得通过拷贝构造来初始化u,但C++17标准要求编译器必须做复制消除:编译器直接在u的内存空间里构造operator+里的v3,连拷贝构造的调用都省了,所以你连Copy construction invoked.的输出都看不到。

要是想观察拷贝构造的调用,可以试试:

  • 把编译标准改成C++14或更早(这时候复制消除是可选的,关了优化就能看到拷贝构造被调用)
  • 或者改operator+,让返回值没法被优化,比如:
    Vector operator+(const Vector& v1, const Vector& v2)
    {
        Vector v3{{1,2,13}};
        Vector v4{{4,5,6}};
        return rand()%2 ? v3 : v4; // 编译器没法确定返回哪个,没法做NRVO
    }
    

验证:让拷贝赋值真正被调用

把main改成这样,你就能看到拷贝赋值的输出了:

int main()
{
    std::vector<int> q{1,2,31};
    Vector w(q);
    Vector r(w);

    Vector u; // 先创建u
    u = w + r; // 这是真正的赋值操作,会触发拷贝赋值

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:37:40