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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…