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

未声明移动构造函数调用拷贝构造,显式删除则编译错误的原因

C++移动构造函数的行为差异解析

问题场景

代码示例1

#include <iostream>
using namespace std;

struct X
{
    X() = default;
    
    X(const X& src)
    {
        cout << "copy" << endl;
    }
};

int main()
{
    X x1;
    
    X x2(move(x1));
}

输出结果:

copy

代码示例2

#include <iostream>
using namespace std;

struct X
{
    X() = default;
    
    X(const X& src)
    {
        cout << "copy" << endl;
    }
    
    X(X&& src) = delete;
};

int main()
{
    X x1;

    X x2(move(x1));
}

编译错误:

error: use of deleted function ‘X::X(X&&)’
   28 |     X x2(move(x1));
      |                  ^

核心困惑

未声明移动构造函数时,编译器未生成默认版本,转而调用了拷贝构造函数;但显式删除移动构造函数后,却直接触发编译错误,这两种行为的差异是什么原因导致的?

原因解析

  • 默认移动构造函数的生成规则
    C++标准明确规定:当类显式声明了拷贝构造函数、拷贝赋值运算符、析构函数中的任意一个时,编译器不会自动生成默认移动构造函数。第一个示例中,因为已经定义了拷贝构造函数,编译器不会生成移动构造函数。此时move(x1)将x1转换为右值引用,但由于没有匹配的移动构造函数,编译器会尝试寻找兼容的构造函数——拷贝构造函数的const X&参数可以绑定到右值(const左值引用的特性),因此最终调用拷贝构造函数,程序正常运行。

  • 显式删除移动构造函数的影响
    当你显式声明X(X&&) = delete;时,这个移动构造函数会被加入类的重载候选集。执行X x2(move(x1));时,编译器会优先匹配参数类型完全吻合的构造函数——也就是被删除的移动构造函数。在重载匹配规则中,右值引用参数比const X&更匹配右值,因此编译器不会降级去调用拷贝构造函数。由于匹配到了一个被删除的函数,直接触发编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:39:55