class A { public: A(int a) : data(a) {} int data; };
class B { public: explicit B(int b) : data(b) {} int data; };
void func_a() { A a = 0; a = 1; } // 編譯通過
void func_b() { B b = 0; b = 1; } // 編譯錯誤:no match for 'operator='
A a = 0 觸發 隱式轉換:編譯器構建臨時 A(0) 再調用拷貝構造。B 標記 explicit 禁止此行為。
T obj = value;void f(T); f(123);T f() { return 123; }vector v; v.push_back(123); T obj(value);、T obj{value};、static_cast<T>(value)。explicit,防止列表初始化隱式轉換。A a = 0; // 相當於 A tmp(0); A a = tmp; 兩次構造+一次拷貝(可能優化)
A a(0); // 直接構造,零開銷
隱式轉換可能產生臨時對象拷貝開銷,且語義模糊(func(10) 是調用 func(int) 還是 func(A)?)。explicit 強制調用者明確意圖。
string(const char*))通常保持隱式,便於字面值賦值。explicit operator bool() 防止布爾上下文意外轉換(如 if (ptr) 允許,但 ptr + 1 禁止)。static A Create(int);explicit 不影響拷貝/移動構造函數(多參數)。explicit 不禁止 static_cast、T{val}、直接初始化。explicit 屬性(C++11 繼承構造函數)。