【发布时间】:2022-11-21 14:09:08
【问题描述】:
我有这个小 sn-p(用 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;
}
问题是我得到main.cpp:27:10: error: use of deleted function 'constexpr A::A(const A&)'
据我所知,有一个编译器约定在定义移动构造函数时隐式删除任何复制操作。如果用户需要它们,则必须明确定义它们。
但是,我尝试使用 auto 作为参数定义一个复制构造函数。如果构造函数签名是A(const A &other),程序运行正常。
由于auto 将被解析为A,编译器仍然认为该特定构造函数已删除的原因是什么?
【问题讨论】:
-
因为
A(const auto &other)不能是拷贝构造函数。这类似于模板构造函数不能是复制构造函数的原因。 -
如果删除移动构造函数,则看不到“Copy constructor called...”,因为
A(const auto &other)不是复制构造函数。 -
“由于 auto 将被解析为 A“:参数中带有占位符 (
auto) 的“函数”声明不是函数,而是函数模板。它不会解析为A。它将接受任何类型作为构造中的参数。正如答案所说,函数模板永远不能是复制构造函数,因此仍然存在被删除的隐式构造函数,并且在重载决策中更好地匹配(因为它不是模板)。