正如预期的那样,以下内容没有编译:
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;
}为什么不考虑已删除的复制构造函数?
发布于 2016-04-13 15:57:40
为什么不考虑已删除的复制构造函数?
它被认为是。它只是没有被使用,所以它是deleted并不重要。来自dcl.fct.def.delete的这条规则是:
隐式或显式引用已删除函数的程序,而不是声明它的程序,是格式错误的程序。[注:.如果函数是重载的,则只有通过重载解析选择该函数时,才会引用该函数。.-end注]
auto a = A{};上的重载解析(在本例中,大括号和父母是等价的)找到了两个构造函数候选:
A(const A&);
A(A&& );选择哪一个候选人是“最可行的”候选人的规则之一是,来自over.match.best
根据这些定义,一个可行的函数F1被定义为比另一个可行函数F2更好的函数,如果. -. -上下文是对函数类型的直接引用绑定(13.3.1.6)的转换函数初始化,F1的返回类型是与被初始化的引用相同的引用类型(即lvalue或rvalue),而F2的返回类型不是
move构造函数与参数是相同类型的引用(rvalue),而复制构造函数则不是。因此,它是首选的,并被选为最佳可行的候选人。由于A(const A&)不是由重载解析选择的,所以我们没有引用该构造函数,所以代码很好。
另一方面,如果我们实际使用了复制构造函数(例如A a(a5)),那么它实际上将尝试使用复制构造函数,这将是错误的。
https://stackoverflow.com/questions/36603628
复制相似问题