1. 修饰构造函数,防止隐式转换,赋值初始化,赋值列表初始化
  2. 修饰转换函数,可以防止隐式转换,但按语境转换除外
  3. explicit 可加在带多个参数的构造方法上(converting to ‘XXX’ from initializer list)
struct B
{
    explicit B(int) {}
    explicit operator bool() const { return true; }
};
 
int main()
{
    B b1(1);            // OK:直接初始化
    B b2 = 1;           // 错误:被 explicit 修饰构造函数的对象不可以赋值初始化
    B b3{ 1 };          // OK:直接列表初始化
    B b4 = { 1 };       // 错误:被 explicit 修饰构造函数的对象不可以赋值列表初始化
    B b5 = (B)1;        // OK:允许 static_cast 的显式转换
    if (b1);            // OK:被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool 的按语境转换
    bool b6(b1);        // OK:被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool 的按语境转换
    bool b7 = b1;       // 错误:被 explicit 修饰转换函数 B::operator bool() 的对象不可以隐式转换
    bool b8 = static_cast<bool>(b1);  // OK:static_cast 进行直接初始化
 
    return 0;
}

从初始化列表隐式转换:

class T{
public:
    T(int a, int b){
        cout << "T(int, int)..." << endl;
        this->a = a;
        this->b = b;
    }
    ~T(){
        cout << "~T()..." << endl;
    }
    void printT(){
        cout << "a = " << a << ", b = " << b << endl;
    }
private:
    int a;
    int b;
};
T func(){
    cout << "in func()..." << endl;
    return {3, 4};
}
int main()
{
    T t = func();
    t.printT();
    return 0;
}

输出:

in func()...
T(int, int)...
a = 3, b = 4
~T()...