8

Can anyone explain why does non-single parameter constructor marked as explicit compile? As far as I understand this is absolutely useless keyword here, so why does this compile without error?

class X
{
public:
    explicit X(int a, int b) { /* ... */}
};
Enlico
  • 23,259
  • 6
  • 48
  • 102
axe
  • 2,331
  • 4
  • 31
  • 53
  • 1
    Possible duplicate of [Explicit keyword on multi-arg constructor?](http://stackoverflow.com/questions/1118680/explicit-keyword-on-multi-arg-constructor) – Frédéric Hamidi Nov 27 '13 at 13:44
  • It works for completeness. Although it indeed does nothing, there's no reason for it cause the compilation to fail. – Guilherme Bernal Nov 27 '13 at 13:44
  • it happens with me regularly. First I have explicit single parameter constructor then I add the second parameter and forget to remove `explicit` – Andriy Tylychko Nov 27 '13 at 13:45
  • 3
    As a rule, the C++ standard tries to specify as uniform rules as possible to make the syntax act as unsurprising as possible when combining feature. So, I think the counter-question should be: what reason is there to explicitly disallow marking such a constructor as `explicit`? – Agentlien Nov 27 '13 at 13:46
  • There can be lots of statements that may do nothing, I don't see why keep them to work. Writing unnecessary things makes the code dirty and one reading the code may spend time to understand why this constructor is marked as explicit while the actual reason is simple: programmer just forgot to remove explicit after adding parameter to constructor. – axe Nov 27 '13 at 13:52
  • The question linked by @FrédéricHamidi is NOT a dupe, as it is obsolete. – jrok Nov 27 '13 at 13:53
  • [This](http://stackoverflow.com/questions/4467142/why-is-explicit-allowed-for-default-constructors-and-constructors-with-2-or-more/4467658#4467658) is a proper dupe. – jrok Nov 27 '13 at 13:55
  • I can definitely see a benefit of allowing `explicit` on constructors with multiple arguments. For example, it makes it easy to create variadic templates to generate constructors without accidentally introducing implicit casts via those constructors. – Agentlien Nov 27 '13 at 13:57
  • @jrok, please vote to close this question as such, then. I already burned my close vote, but there can be several duplicates to one question. – Frédéric Hamidi Nov 27 '13 at 13:58
  • 1
    Guys, you are talking about C++11, I'm talking about C++98 or C++03 when there was no `{}` initialization, no variadic templates and so on... – axe Nov 27 '13 at 13:58
  • 1
    @FrédéricHamidi I did that. OP: If you're interested in C++03 answers, you should explicitly say so. It's 2013, mind you. – jrok Nov 27 '13 at 13:59
  • Explicit operator - yes, explicit constructor - no – axe Nov 27 '13 at 14:00
  • Yes, it's 2013 :) but still there is no compiler completely supporting C++11, right? – axe Nov 27 '13 at 14:01
  • Actually, both gcc and clang fully support C++11. – Agentlien Nov 27 '13 at 14:01
  • My gcc doesn't support C++11 fully, probably the version is old. Anyway, there is special tag for C++11 here, I used C++ tag. – axe Nov 27 '13 at 14:02
  • 2
    These days the C++ is taken as implying "the current standard today", and the C++11 seems to be used for *C++11 only* issues. So it is well worth specifying C++03 when you ask a question, otherwise most people will assume C++11, even if you don't have that tag. – juanchopanza Nov 27 '13 at 14:06
  • I do think it is a reasonable assumption that a question in C++ is taken to mean the C++11 standard, seeing as it has been the international standard for defining what C++ is for 2 years already and that there are multiple fully conforming compilers. – Agentlien Nov 27 '13 at 14:07

2 Answers2

10

In C++03, and in this particular case, it makes no sense for a two parameter constructor to be marked explicit. But it could make sense here:

explicit X(int i, int j=42);

So, marking a two parameter constructor with explicit does not have to be an error.

In C++11, this use of explicit would prevent you from doing this:

X x = {1,2};
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Yes, but in my example compiler can understand that there is no sense and constructor cannot be called with one argument, so it could give a compile time error. – axe Nov 27 '13 at 13:45
  • 5
    @axe Yes, I agree, perhaps the rules of the language could have been stricter about this. The question is whether it is worth adding more complications to the rules for the potential benefit. Now, fast forward to 2011 and C++11, and `explicit` *does* serve a purpose in multi-parameter constructors. So one could argue that it was lucky that the rule was not made stricter originally. – juanchopanza Nov 27 '13 at 13:59
  • OK. I think we can close the question. Thanks to everyone. – axe Nov 27 '13 at 13:59
9

Not entirely true.

In C++11, constructors with multiple arguments can be implicitly converted using brace initialisation.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483