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?

Original source