Why is explicit allowed for default constructors and constructors with 2 or more (non-default) parameters?
c++, constructor, explicit, explicit-constructor, language-design
Solution
One reason certainly is because it doesn't hurt.
One reason where it's needed is, if you have default arguments for the first parameter. The constructor becomes a default constructor, but can still be used as converting constructor
struct A {
explicit A(int = 0); // added it to a default constructor
};
C++0x makes actual use of it for multi parameter constructors. In C++0x, an initializer list can be used to initialize a class object. The philosophy is
if you use `= { ... }`, then you initialize the object with a sort of "compound value" that conceptually represents the abstract value of the object, and that you want to have converted to the type.
if you use a `{ ... }` initializer, you directly call the constructors of the object, not necessarily wanting to specify a conversion.
Consider this example
struct String {
// this is a non-converting constructor
explicit String(int initialLength, int capacity);
};
struct Address {
// converting constructor
Address(string name, string street, string city);
};
String s = { 10, 15 }; // error!
String s1{10, 15}; // fine
Address a = { "litb", "nerdsway", "frankfurt" }; // fine
In this way, C++0x shows that the decision of C++03, to allow explicit on other constructors, wasn't a bad idea at all.
Problem
I understand that constructors with one (non-default) parameter act like implicit convertors, which convert from that parameter type to the class type. However, `explicit` can be used to qualify any constructor, those with no parameters (default constructor) or those with 2 or more (non-default) parameters. Why is explicit allowed on these constructors? Is there any example where this is useful to prevent implicit conversion of some sort?