explicit

一般认为 explicit 是用在单参数构造函数 上防止隐式类型转换的。但如果参数有多个,explicit 关键字也有其他的作用。

explicit 可以阻止 {} 推导

https://stackoverflow.com/a/39122237/

可以参考另一篇文章:{ } Syntax。

struct Foo { Foo(int, int) {} };
struct Bar { explicit Bar(int, int) {} };

Foo f1(1, 1); // ok
Foo f2 {1, 1}; // ok
Foo f3 = {1, 1}; // ok

Bar b1(1, 1); // ok
Bar b2 {1, 1}; // ok
Bar b3 = {1, 1}; // NOT OKAY

Bar many_bars[] = { {1, 1} };     // ERROR explicit阻止了 {1, 1} 被推导成 Bar{1, 1}
Bar many_bars2[] = { Bar{1, 1} }; // okay

阻止“去掉默认值是单参数构造函数”的隐式转换

如果将来某个构造函数除了第一个参数之外的其他参数有了默认值,则会引起和单参数构造函数一样的隐式转换问题。

class A {
    public:
        A( int b, int c=0 ) {} // A 可以从 int 隐式转换而来
};