What is your procedure when switching over an enum where every enumeration is covered by a case? Ideally you\'d like the code to be future proof, how do you do that?
<
LLVM Coding Standards' opinion is: Don’t use default labels in fully covered switches over enumerations
Their rationale is:
-Wswitchwarns if a switch, without a default label, over an enumeration does not cover every enumeration value. If you write a default label on a fully covered switch over an enumeration then the-Wswitchwarning won’t fire when new elements are added to that enumeration. To help avoid adding these kinds of defaults, Clang has the warning-Wcovered-switch-defaultwhich is off by default but turned on when building LLVM with a version of Clang that supports the warning.
Based on this , I personally like doing:
enum MyEnum { A, B, C };
int func( MyEnum val )
{
boost::optional result; // Or `std::optional` from Library Fundamental TS
switch( val )
{
case A: result = 10; break;
case B: result = 20; break;
case C: result = 30; break;
case D: result = 40; break;
}
assert( result ); // May be a `throw` or any other error handling of choice
... // Use `result` as seen fit
return result;
}
If you choose to return on every case of the switch, you don't need boost::optional: simply call std::abort() or throw unconditionally just after the switch block.
It's nonetheless important to remember that maybe switch is not the best design tool to begin with (as already stated in @UncleBens answer): Polymorphism or some type of lookup-table could place a better solution, especially if your enum has a lot of elements.
PS: As a curiosity, the Google C++ Style Guide makes an exception to switchs-over-enums not to have default cases:
If not conditional on an enumerated value, switch statements should always have a default case