显式复制构造函数的行为

Behaviour of explicit copy constructor

我有以下代码:

#include <iostream>

struct A {
  A(int x=1, int y=1) : x(x), y(y) { }
  A(const A& other) : x(other.x), y(other.y) { }

  operator bool() const { return !x && !y; }

  friend std::ostream& operator<<(std::ostream& os, const A& a) {
    os << a.x << "," << a.y << "\n";
    return os;
  }

  int x;
  int y;
};

int main(int argc, char const *argv[]) {
  A const A10x10(10, 10);
  A a;
  std::cout << a;
  A aa = A10x10;
  std::cout << aa;
  return 0;
}

以上打印:

1,1
10,10

当我将复制构造函数更改为显式(即 explicit A(const A& other);)时,我得到:

1,1
0,1

我在(显式)复制构造函数中放置了一个 print 语句,实际上它没有被调用。为什么会这样? explicit 有什么区别?

我正在使用 C++17,用 Clang10 编译。

这个:

A aa = A10x10;

执行复制初始化。复制初始化通过将对象转换为正在初始化的对象的类型来工作。但是,复制初始化是通过隐式转换来实现的。并且隐式转换 不能 调用 explicit 构造函数。

即使是拷贝构造函数

现在无论如何,你会认为你会得到一个编译错误。但你没有。为什么?因为 A 可以通过 user-defined 隐式转换为 bool。并且 bool 可以通过标准转换转换为 intA 实际上可以从 int 类型的单个值构造。虽然隐式转换只允许一次 user-defined 转换,但它确实允许 user-defined 转换后跟标准转换。

事情就是这样。这就是为什么当复制构造函数是 explicit.

aa 中的第一个值是 0

一般来说,总是使operator boolexplicit从不创建复制构造函数explicit.