Reputation: 67292
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
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
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