0

I have a function to change the state of an LED that takes in an enum argument with three possible values:

enum class Command { Off, On, Toggle };

void led(Command);

I'd like to be able to use the led() function with bool arguments: led(true) or led(false).

I realize that I can overload the void led(Command) function with a void led(bool) but I feel like this shouldn't be necessary.

Specifically, I'm thinking I should be able to define an operator that provides an explicit conversion from bool to Command. I haven't been able to find the syntax for this. My current best guess is:

inline constexpr operator Command(bool on) { return on ? Command::On : Command::Off; }

But it seems the operator overloads can only be declared inside classes? I can see how I could do this with a full class instead of an enum class, but that seems heavy here.

Is what I want to do possible?

2
  • 2
    That's the typical use case of function overloading, I doubt there's a better solution than void led(bool) Commented Apr 2, 2021 at 18:17
  • enum class only does so much. If you want it to have behavior, you may want to use class Command { public: enum Op { Off, On, Toggle}; /*...*/}; and then you have a place to add in member functions, conversion constructors, explicit operator bool, et cetera. Commented Apr 2, 2021 at 18:18

2 Answers 2

1

I think that function overloading was designed exactly for this need: same action, different input types. I'd change the method name though, usually a verb makes the action clearer and improves the code readability.

Something like:

void set_led(Command);
void set_led(bool on){
    if(on)
        return set_led(On);
    return set_led(Off);
}
Sign up to request clarification or add additional context in comments.

8 Comments

Well, you wouldn't return the results of calling a void function, but otherwise yeah.
@Nathan that's perfectly legal in c++ (ideone.com/GroC04). Mat's just making it so they don't need an else statement or a separate line for the return.
Huh, didn't know that! Neat.
@Nathan Ehm, I didn't knew that either, that's captain-giraffe 's code! :-) Since he has several orders of magnitude more reputation than me, I have nothing to complain
Is there a reason to not use set_led(on ? Command::On : Command::Off)? Feels shorter and easier to read to me.
|
1

The whole purpose of enum class that you're using is to prevent comparisons directly to int (which bool has an implicit conversion to). So as long as you're using an enum class, there's no easy way to do this implicitly.

That said, you can take advantage of the fact that your Off is the first item of the enum (it'll convert to int 0) and On is the second (which'll convert to 1). Since this matches the implicit bool to int conversions for false and true, you can do:

led(Command(true));
led(Command(false));

See it in action: https://ideone.com/iWrc3s


Alternatively, you can switch to just an enum instead of an enum class, which will allow your Command to be implicitly converted to an int. Since bool also has an implicit conversion to int, you can change your led() method to take an int and then call it directly with:

led(true);
led(false);

See it in action: https://ideone.com/HF0cxI

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.