Please note that out in switch(out) is of enum type of Outcome. The behavior is correct (as the code is listed in a famous textbook). I just could not figure why the code is not what we are familiar with (I guess it must have something to do with enum type that makes it work that way). Can anyone explain it?
The post of guestgulkan makes sense: as return is used, we do not need break statements anymore.
Yes, I got it: the value of Outcome can only be one of WIN, LOSE or DRAW in the enum of Outcome. It is impossible for a Outcome variable to have any other values than WIN, LOSE or DRAW (if it does, the offending assignment statement would result in a compiling error, right?) There is no default case for the code to handle. So the default is put at the topmost. The code would be trapped in an infinite loop if we add even a single additional value to the enum but failing to deal with it in the switch statement (default is not handled at all):
1 2 3 4 5 6 7 8 9 10
enum Outcome { WIN, LOSE, DRAW, ADDED };
ostream& operator<<(ostream& os, const Outcome out) {
switch(out) {
default:
case WIN: return os << "win";
case LOSE: return os << "lose";
case DRAW: return os << "draw";// there is no ADDED
// case ADDED : return os << "added"; // must be added here. otherwise infinite loop
}
an enum value is an integeral type (integer) - and therefore can be used anywhere an integral value is expected - for example in a switch statement.
(however going the other way from integer to enum is not implicitly allowed).
By the way, the default case is handled - it simply falls through to the WIN case. So anything other than LOSE or DRAW (or an explicit WIN) is treated as WIN.
As all the possible values has their own case labels, the default label will never be executed. The default label can be omitted and the behavior remains exactly the same. But the fact that the default is still there is strange...
EDIT: new posts: ADDED, that could be a solution, but I would still omit the default, because my complier gives me a warning if I'm missing even one case label for an enum.
I agree withR0mai. The default is misleading. If I were to write it, the code would be more understandable by simple removing the default statement as follows:
1 2 3 4 5 6 7 8
enum Outcome { WIN, LOSE, DRAW }; // enum can not have "values" other than those listed
ostream& operator<<(ostream& os, const Outcome out) {
switch(out) {
case WIN: return os << "win";
case LOSE: return os << "lose";
case DRAW: return os << "draw";
}
EDIT: my compiler of VS C++ 2008 Prof does not generate any warning against this default usage. Not a good compiler for this type of the "abnormal".
It is always best to include a default case in switch statements, even if all cases are handled. It helps to detect uninitialized variables or corrupted variables, because in these cases the default case may very well be
executed.
Some compilers (if not all--I'm not sure if it is part of the standard) will generate warnings if a default case is not provided.