c++中explicit修饰词

explicit修饰构造函数时,不允许隐式转换和隐式拷贝初始化。它只能出现在修饰构造函数时。

备注:含有一个参数的构造函数,如果其参数没有默认值,函数没有explicit修饰,则该构造函数可以叫做转换构造函数。拷贝、移动构造函数和用户定义的转换函数可能是函数模版;explicit的含义是不发生转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct A
{
A(int) { } // 可转换构造函数
A(int, int) { } // 可转换构造函数 (C++11)
operator bool() const { return true; }
};

struct B
{
explicit B(int) { }
explicit B(int, int) { }
explicit operator bool() const { return true; }
};

int main()
{
A a1 = 1; // 正确: 拷贝初始化调用 A::A(int)
A a2(2); // 正确: 直接初始化调用 A::A(int)
A a3 {4, 5}; // 正确: 直接列表初始化调用 A::A(int, int)
A a4 = {4, 5}; // 正确: 拷贝列表初始化调用 A::A(int, int)
A a5 = (A)1; // 正确: 显式转换执行 static_cast
if (a1) ; // 正确: A::operator bool()
bool na1 = a1; // 正确: 拷贝初始化调用 A::operator bool()
bool na2 = static_cast<bool>(a1); // 正确: static_cast 执行直接初始化

// B b1 = 1; // 错误:拷贝初始化不会调用 B::B(int)
B b2(2); // 正确: 直接初始化调用 B::B(int)
B b3 {4, 5}; // 正确: 直接列表初始化调用 B::B(int, int)
// B b4 = {4, 5}; // 错误: 拷贝列表初始化不会调用 B::B(int,int)
B b5 = (B)1; // 正确: 显式转换执行 static_cast
if (b2) ; // 正确: B::operator bool()
// bool nb1 = b2; // 错误: 拷贝初始化不会调用 B::operator bool()
bool nb2 = static_cast<bool>(b2); // 正确: static_cast 执行直接初始化
}

参考:
en.cppreference.com/w/cpp/language/explicit