When applied to a single-argument constructor, prevents that constructor from being used to perform implicit conversions.
class MyVector {
public:
explicit MyVector(uint64_t size);
};
MyVector v1(100); // ok
uint64_t len1 = 100;
MyVector v2{len1}; // ok, len1 is uint64_t
int len2 = 100;
MyVector v3{len2}; // ill-formed, implicit conversion from int to uint64_t
Since C++11 introduced initializer lists, in C++11 and later, explicit
can be applied to a constructor with any number of arguments, with the same meaning as in the single-argument case.
struct S {
explicit S(int x, int y);
};
S f() {
return {12, 34}; // ill-formed
return S{12, 34}; // ok
}
When applied to a conversion function, prevents that conversion function from being used to perform implicit conversions.
class C {
const int x;
public:
C(int x) : x(x) {}
explicit operator int() { return x; }
};
C c(42);
int x = c; // ill-formed
int y = static_cast<int>(c); // ok; explicit conversion