问题描述
#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
可以通过用户定义的转换隐式转换为bool
。 bool
可通过标准转换转换为int
。实际上,A
可以由类型为int
的单个值构造。尽管隐式转换仅允许一个用户定义的转换,但它确实允许用户定义的转换以及随后的标准转换。
这就是发生的情况。这就是为什么当复制构造函数为aa
时explicit
中的第一个值为0的原因。
通常来说,总是设为operator bool
explicit
。并且从不使副本构造函数explicit
。