Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 移动构造函数绕过复制构造函数_C++_Constructor - Fatal编程技术网

C++ 移动构造函数绕过复制构造函数

C++ 移动构造函数绕过复制构造函数,c++,constructor,C++,Constructor,正如预期的那样,未编译以下内容: class A { public: A() = default; //A(A&&) = default; A(const A&) = delete; int x; }; int main() { auto a4 = A{}; // not ok, copy constructor is deleted auto a5 = A(); // not ok, copy constructor i

正如预期的那样,未编译以下内容:

class A {
public:
    A() = default;
    //A(A&&) = default;
    A(const A&) = delete;
    int x;
};

int main()
{
    auto a4 = A{}; // not ok, copy constructor is deleted
    auto a5 = A(); // not ok, copy constructor is deleted
    return 0;
}
但是,如果添加了移动构造函数,即使显式删除了复制构造函数,也会编译以下内容:

class A {
public:
    A() = default;
    A(A&&) = default;
    A(const A&) = delete;
    int x;
};

int main()
{
    auto a4 = A{}; // now ok, even though copy constructor is deleted
    auto a5 = A(); // now ok, even though copy constructor is deleted
    return 0;
}
为什么不考虑删除的副本构造函数

为什么不考虑删除的副本构造函数

这是值得考虑的。它只是没有被使用,所以它被删除的事实并不重要。[dcl.fct.def.delete]中的规则是:

隐式或显式引用已删除函数而不是声明它的程序是格式错误的。 [注:[…]如果函数 是重载的,仅当通过重载解析选择函数时才引用它。[…]-结束注释]

自动a=a{}上的重载解析;在这种情况下,大括号与括号是等效的。找到两个候选构造函数:

A(const A&);
A(A&& );
选择最佳可行候选人的规则之一是,从[over.match.best]开始:

根据这些定义,可行函数F1被定义为比另一个可行函数更好的函数 F2如果[…],然后 — [...] -上下文是引用的直接引用绑定13.3.1.6的转换初始化函数 对于函数类型,F1的返回类型与 正在初始化引用,并且F2的返回类型不是

move构造函数与参数的引用rvalue类型相同,而copy构造函数则不同。因此,它是首选,并被选为最佳可行的候选人。由于不是通过重载解析来选择acost A&的,因此我们没有引用该构造函数,因此代码很好


另一方面,如果我们实际使用复制构造函数,例如aa5,那么实际上会尝试使用复制构造函数,这将是格式错误的

因为A{}或A产生一个可变的非常量纯右值。auto a6=a5;这可能是个错误,这对我来说是个答案。这也解释了为什么在两个构造函数上交换delete和default时它不会编译。重载解析“锁定”移动构造函数(如果存在)。