2

Why is the below code invalid (at least using Visual Studio 2010 or ideone)?

// E.h
enum E
{
  AN_E_VALUE
};

// C.h
class C
{
public:
  explicit C(E e) // explicit keyword is optional
  {}

  void Foo() {}
};

// main.cpp
int main(int argc, char** argv)
{
  C c(AN_E_VALUE);      // fine
  C(AN_E_VALUE);        // error
  C(AN_E_VALUE).Foo();  // fine
  return 0;
}

If the parameter is anything but a single enumerated type, it works fine.

The compiler understands the erroneous call as one with 0 arguments where 1 is expected. Why is this?

zyndor
  • 1,418
  • 3
  • 20
  • 36
  • 1
    Compiler interprets that as a variable declaration. Your class has no default-constructor. Error. – David G Nov 27 '14 at 18:28
  • Yup, this is a vexing parse. The solution (if you have C++11), is to do `C{AN_E_VALUE}`. – David G Nov 27 '14 at 18:30
  • That's great -- indeed, adding the default constructor gets rid of the error. However, if I add it as private - as default constructing objects of class C does not make sense and should not be allowed - we're back to square one. EDIT: been staring at it too long... the compiler-generated default constructor _is_ private. #squareone – zyndor Nov 27 '14 at 18:33
  • The solution is *not* to add a default-constructor, but to choose a different way of creating the object. `C(AN_E_VALUE)` is interpreted as a variable-declaration, it doesn't call the explicit constructor. What you need is `C{AN_E_VALUE}` or one of the other variants you showed. – David G Nov 27 '14 at 18:36
  • Also, the compiler-generated default-constructor is public by default but your user-declared constructor inhibited its creation. – David G Nov 27 '14 at 18:37
  • 2
    Instead of `C{AN_E_VALUE};`, `(C(AN_E_VALUE));` is also a valid workaround, and more portable: it'll work even if you've got to support pre-C++11 compilers. –  Nov 27 '14 at 18:43
  • @0x499602D2 But of course -- thank you for the clarification. No more edits for me today. – zyndor Nov 27 '14 at 18:44

1 Answers1

3
C(AN_E_VALUE);

This declares an object of type C with name AN_E_VALUE. The error complains about the fact that you need a default constructor to initialize AN_E_VALUE, but no default constructor exists (and none is implicitly declared).
Have you ever tried this?:

int(a);

That's essentially accomplishes the same thing. Perhaps check out this question.

Community
  • 1
  • 1
Columbo
  • 60,038
  • 8
  • 155
  • 203