我有这个小片段(用 编译g++
),其中定义了一个移动构造函数:
#include <iostream>
using namespace std;
class A {
public:
A() = delete;
A(int value) : value(value) {}
void operator=(const auto &other) = delete;
~A() { cout << "Destructor called..." << endl; }
A(const auto &other) {
cout << "Copy constructor called..." << endl;
value = other.value;
}
A(const A &&other) {
cout << "Move constructor called..." << endl;
value = other.value;
}
private:
int value;
};
int main() {
A p1(2);
A p2(p1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是我得到了main.cpp:27:10: error: use of deleted function 'constexpr A::A(const A&)'
据我了解,有一个编译器约定在定义移动构造函数时隐式删除任何复制操作。如果用户需要它们,则必须明确定义它们。
但是,我尝试定义一个用作auto
参数的复制构造函数。如果构造函数签名是,则A(const A &other)
程序运行良好。
既然auto
will 被解析为A
,编译器仍然认为该特定构造函数被删除的原因是什么?
既然 auto 将被解析为 A,那么编译器仍然认为该特定构造函数已被删除的原因是什么?
因为当在函数的参数中使用时A::A(const auto &)
不能是复制构造函数,所以该函数声明/定义实际上是针对函数模板的。auto
基本上A::A(const auto&)
是一个模板化的构造函数。但根据class.copy.ctor ,模板化构造函数不能是复制构造函数。
如果类的第一个参数的类型
X
为 、 或 ,并且没有其他参数或所有其他参数都具有默认参数 ([dcl.fct.default]),则类的非模板构造函数是X&
复制构造函数const X&
。volatile X&
const volatile X&
(强调我的)
由于您已经定义了移动构造函数A::A(const A&&)
,因此合成的复制构造函数A::A(const A&)
将被隐式删除。但请注意,隐式删除的复制构造函数A::A(const A&)
参与重载解析,并且仍然比模板化构造函数更匹配A::A(const auto&)
。因此,选择了复制因子,但由于它被删除(隐式),我们得到了上述错误。