class Vector
{
public:
Vector(size_t len); // construct a Vector
// 'len' elements long
};
What happens when someone misuses this?
void print(const Vector& v); print(3);
The call in fact creates a temporary Vector, 3 elements long and passes it to print. For a class designer, this is a real problem for writing a usable class. Obviously the constructors are needed but they are not always suitable as conversions as well.
Nathan Myers proposed a solution that would allow constructors to be designated 'non-converting' (Nathan also contributed some new material to this page). The committee discussed the actual spelling of the new keyword for some time -- new keywords are somewhat a religious issue in language design -- before agreeing on explicit.
The above example can now be rewritten:
class Vector
{
public:
explicit Vector(size_t len);
//...
};
print(3); // fails because there is no conversion
The explicit keyword indicates that the constructor should not be considered for implicit conversions to the given class type, only for explicit conversions:
Vector v1(3); // OK Vector v2 = Vector(3); // OK Vector v3 = 3; // error: no conversion
Besides preventing errors, explicit constructors prevent unnecessary ambiguities from arising in your code that would otherwise require a type cast. For example, given the declarations:
class BigNum
{
public:
BigNum(long l);
};
void f(const Vector& v);
void f(const BigNum& b);
If the Vector constructor had not been declared explicit, then the call:
f(7);
would be ambiguous, resulting in a compile-time error. With the explicit Vector constructor, the second f() is chosen.