C++ 为什么在删除“移动构造函数”时使用“复制构造函数”?

C++ 为什么在删除“移动构造函数”时使用“复制构造函数”?,c++,c++11,constructor,copy-constructor,move-semantics,C++,C++11,Constructor,Copy Constructor,Move Semantics,作为主题,相关代码为: #include <iostream> class ABC { public: ABC() { std::cout<< "default construction" << std::endl; } ABC(const ABC& a) { std::cout << "copy construction" <&

作为主题,相关代码为:

#include <iostream>     

class ABC     
{  public:  
    ABC() 
    {
        std::cout<< "default construction" << std::endl;
    }

    ABC(const ABC& a) 
    {
        std::cout << "copy construction" << std::endl;
    } 

    ABC(const ABC&& a) 
    {
        std::cout << "move construction" << std::endl;
    }
};                         

int main()   
{  
   ABC c1 = ABC();  

   return 0;  
}
如果删除上面的移动构造函数,则输出为:

default construction
copy construction
为什么在删除
移动构造函数
时可以使用
复制构造函数
呢?您可以看到,如果有用户定义的
移动构造函数
,编译器更喜欢使用
移动构造函数

根据一些文档,编译器提供了一个默认的
移动构造函数
**,那么为什么编译器不使用默认的
移动构造函数
? 我是C++初学者,很感谢能对这个问题有所帮助。 根据一些文档,编译器提供了一个默认的
move构造函数

让我们看一些文档。以下内容来自

如果[conditions],则编译器将使用签名
T::T(T&&)
将移动构造函数声明为其类的非显式内联公共成员

你说得对。编译器确实在正确的条件下提供了一个defualt move构造函数。然而,这些条件很重要。您似乎知道的第一个条件是:不能有用户定义的移动构造函数。因此,只剩下以下条件列表:

  • 没有用户声明的副本构造函数
  • 没有用户声明的副本分配运算符
  • 没有用户声明的移动分配运算符
  • 没有用户声明的析构函数

就这样。用户定义的复制构造函数阻止编译器提供默认的移动构造函数。因此没有可使用的移动构造函数。

感谢您的澄清。那么为什么在删除了
移动构造函数时可以使用
复制构造函数
?您可以看到,如果有用户定义的
移动构造函数
,编译器更喜欢使用
移动构造函数
。如果
移动构造函数
不可用,则通过正常函数匹配选择
复制构造函数
const ABC&
可以绑定到使用
ABC()
创建的临时文件。在存在
move-ctor
的情况下,
ABC&
更匹配,因为不需要
const转换@sunshilong369@User10482谢谢你的解释。是(C++的ABC和可以绑定到临时创建的ABC())由C++标准开发的吗?还有一个问题,为什么编译器抱怨“<代码> abc(CONSTABC)<代码>被ABC(ABC)?@孙世龙369右替换,编译器更喜欢使用移动构造函数而不是复制构造函数。然而,它更倾向于使用存在的东西,而不是不存在的东西。复制构造函数确实适合此用途,只是不如移动构造函数好。@sunshilong369您的构造从一个临时的
ABC
对象开始,然后将该对象传输(移动或复制)到另一个对象。也就是说,move或copy构造函数的参数是临时对象。因此,询问
ABC(ABC&)
就接近于询问
ABC(const ABC&)
并不是一个动作。删除常量:
ABC(ABC&&)
@谢谢。你能更详细地解释一下吗?我有点困惑,因为这个代码(删除关键字
const
)[确实可以编译。似乎我错了。Cppreference说
T(const T&)
不算作移动向量。无论如何。从阅读开始,然后按照专用向量/作业页的链接进行操作。@besc你认为
T(T&&)
(无关键字
const
)算作移动向量吗?
default construction
copy construction