为什么auto不能用来定义隐式删除的构造函数

use*_*010 4 c++ gcc

我有这个小片段(用 编译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)程序运行良好。

既然autowill 被解析为A,编译器仍然认为该特定构造函数被删除的原因是什么?

use*_*570 7

既然 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&)。因此,选择了复制因子,但由于它被删除(隐式),我们得到了上述错误。