9

If I define an enum like so:

enum Foo : bool { Left = false, Right = true };

then try to construct one from a boolean like so:

int main (int ac, const char **av) {
    Foo foo ( ac > 1 );
    cout << boolalpha << bool(foo) << endl;
    return 0;
}

it fails, but works with an extra constructor like so:

Foo foo ( Foo( ac > 1 ) );

Why is this? I thought Foo foo (...) was an explicit constructor call?

Will Crawford
  • 264
  • 4
  • 13
  • (orthogonal) Suggestion: use `enum class Foo` and `static_cast()`. – lorro Jun 29 '16 at 10:01
  • In `Foo foo( Foo( ac > 1 ) )`, the second `Foo` is in fact a cast. – Jarod42 Jun 29 '16 at 10:09
  • 1
    I guess `Foo( ac > 1 ) ` is typecasting result of `(ac > 1)` to `Foo`. And `Foo foo ( Foo( ac > 1 ) );` involves calling byfefault copy constructor of `Foo`. – sameerkn Jun 29 '16 at 10:09
  • I guess that answers the question :) thankyou both (and thankyou for the suggestion, although I prefer constructor syntax for the conversion; I guess actually I *would* like the conversion to be implicit). – Will Crawford Jun 29 '16 at 10:13
  • 1
    Does this answer your question? [Converting integral type to enum: functional cast vs initialization](https://stackoverflow.com/questions/50070130/converting-integral-type-to-enum-functional-cast-vs-initialization) – Artyer Dec 01 '21 at 19:18

2 Answers2

3

I don't think you can do this:

Foo foo ( ac > 1 );

Suppose you define Foo enum as:

enum Foo : bool { Left = false };

What would happen if you called:

Foo foo(true);

You don't have appropriate enum value for what you want to initialize with.

MaciekGrynda
  • 583
  • 2
  • 13
  • That's not really answering the question *per se*, although it's a valid caveat to casting involving `enum`s in most cases. – Will Crawford Jun 29 '16 at 11:06
  • This is incorrect. As long as the value is representable by the underlying type of the enum (in this case `bool`) it can be cast to the enum type, even if it isn't explicitly enumerated (See: https://stackoverflow.com/q/18195312) – Artyer Dec 01 '21 at 19:17
3

Foo foo ( ac > 1 ); That's a case of the C++ most vexing parse. It's a function declaration that does nothing.

PodHunter
  • 74
  • 4
  • 3
    How can the comparison `(ac > 1)` be interpreted as part (probably *argument*) of a function declaration? – Reizo Sep 23 '20 at 19:38
  • Read the linked article about the C++ Most Vexing Parse! – PodHunter Dec 14 '22 at 15:01
  • 2
    yes, it doesn't say anything about how `(ac > 1)` would be parsed as function argument type. That's why I asked. – Reizo Dec 21 '22 at 18:59
  • 1
    Reizo is right: this is not a most vexing parse case because `ac > 1` cannot be parsed as a function argument, so it has to be parsed as an expression (and therefore the whole declaration is parsed as an initializer rather than a function declaration). – Chris Badger Mar 01 '23 at 02:14