LiraNuna
LiraNuna

Reputation: 67292

What is the purpose of the explicit keyword on a multi-argument constructor?

I recently came across some weird looking class that had three constructors:

class Class
{
    public:
        explicit Class(int );

        Class(AnotherClass );

        explicit Class(YetAnotherClass, AnotherClass );

    // ...
}

This doesn't really make sense to me - I thought the explicit keyword is to protect compiler chosen construction from a foreign type.

Is this allowed? If it it, what does it mean?

Upvotes: 35

Views: 8349

Answers (2)

Jan Schultke
Jan Schultke

Reputation: 39763

First of all, constructors with multiple parameters can be used for implicit conversions too:

struct S {
    S(int x, int y = 0);
};

S s = 123; // OK, x = 123, y = 0

While explicit was pointless prior to C++11 in some cases, there was no real benefit to banning it, only extra effort. Even if C++ language designers would have wanted to ban explicit where it's pointless, the rule would be relatively complicated, and not as simple as "allowed for ≤ 1 parameter". See Why is explicit allowed for default constructors and constructors with 2 or more (non-default) parameters? for more on the topic of language design.

Secondly, since C++11, explicit forbids list-initialization without specifying the type:

struct T {
    explicit T(int x, int y);
};

T a{1, 2};    // OK
T b = {1, 2}; // error

T foo() {
    return T{1, 2}; // OK
    return {1, 2};  // error
}

Upvotes: 0

Roger Lipscombe
Roger Lipscombe

Reputation: 91885

In C++11 multi-parameter constructors can be implicitly converted to with brace initialization.

However, before C++11 explicit only applied to single-argument constructors. For multiple-argument constructors, it was ignored and had no effect.

Upvotes: 54

Related Questions