A constructor declared without the function-specifier explicit specifies a conversion from the types of its parameters (if any) to the type of its class. Such a constructor is called a converting constructor. [ Example:
struct X {
X(int);
X(const char*, int =0);
X(int, int);
};
void f(X arg) {
X a = 1; // a = X(1)
X b = "Jessie"; // b = X("Jessie",0)
a = 2; // a = X(2)
f(3); // f(X(3))
f({1, 2}); // f(X(1,2))
}— end example ]
[ Note: An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax or where casts ([expr.static.cast], [expr.cast]) are explicitly used; see also [over.match.copy]. A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value-initialization. [ Example:
struct Z {
explicit Z();
explicit Z(int);
explicit Z(int, int);
};
Z a; // OK: default-initialization performed
Z b{}; // OK: direct initialization syntax used
Z c = {}; // error: copy-list-initialization
Z a1 = 1; // error: no implicit conversion
Z a3 = Z(1); // OK: direct initialization syntax used
Z a2(1); // OK: direct initialization syntax used
Z* p = new Z(1); // OK: direct initialization syntax used
Z a4 = (Z)1; // OK: explicit cast used
Z a5 = static_cast<Z>(1); // OK: explicit cast used
Z a6 = { 3, 4 }; // error: no implicit conversion
— end example ] — end note ]
A non-explicit copy/move constructor ([class.copy]) is a converting constructor. [ Note: An implicitly-declared copy/move constructor is not an explicit constructor; it may be called for implicit type conversions. — end note ]