Why can't I assign the wrong enum element, but can compare against the wrong enum element?
With the following C++ definitions:
enum EnumA {
EA_Element = 1
};
enum EnumB {
EB_Element = 10
};
the following code won't compile and tha开发者_JS百科t only makes sense:
EnumA variable;
variable = EB_Element; // won't compile
but the following code does compile:
EnumA variable = EA_Element;
if( variable == EB_Element ) { //will compile
}
although it can't make any sense - different enums are compared and such code is likely erroneous.
Why are these seemingly identical situations handled differently in C++?
It will compile because "By default enums are converted to integers for arithmetical operations." (In: The C++ programming language)
That argument is correct as, I have seen that any enum
type can be compared to any enum
type. That's because for comparison purpose, enum
variables and values should be converted to integral type (such as int
). Certain compiler do raise the warning.
Such argument can hold true for comparison between unsigned int
, int
, size_t
etc., but may be they all are limited to a compiler warning for the same reason.
However, this issue is addressed in C++0x with enum class
(they haven't changed the existing enum
behavior to maintain compatibility).
Its not that its impossible, its just that your compiler considers them to be two different data types when they are both just integers. So a simple typecast would resolve the issue.
EnumA variable;
variable = (EnumA)EB_Element;
Welcome to C++!
for something even funnier try this:
#include <string>
int main(int argc, const char *argv[])
{
std::string s;
s = 3.141592654;
return 0;
}
why does it compile? The reason is that the language rules say so.
In this funky case the "official" explanation about why this example compiles is that it seemed right to allow std::string::operator+=(char)
(IMO ok and logical from a pragmatic point of view) and "therefore" also assignment from char (IMO illogical non-sequitur). But chars are ints (illogical, but C heritage) and doubles can be implicitly converted to ints (illogical, but C heritage). Therefore in C++ it's illogical (but legal) to assign a double to a string.
Don't feel bad if you didn't know, most C++ programmers I shown this were puzzled by why such a nonsense compiles and thought about either other semantic or compiler bugs.
In the case of your question the reason is that enums are like ints in some context (probably because of heritage on use cases) but not like ints in some other context. It's absurd but it's what the standard mandates.
If you feel uncomfortable with this apparently absence of logic please remember that C++ is mostly the result of a long history and even of a committee (!) so logic doesn't really have much to do with it. This also implies that one cannot use logic to avoid studying C++: no matter how intelligent you are there is no way you can guess historic accidents and committee political decisions.
The high C++ complexity, this absence of logic in many places and the presence of undefined behavior daemons
instead of runtime error angels
is also what IMO basically rules out learning C++ by experimentation.
Pick a good book (or a few) and read it (them) cover to cover... unfortunately there is no other way. My suggestions are: "The C++ Programming Language" (Stroustrup), "Effective C++" & "More effective C++" (Meyers), "C++ FAQs" (Cline/Lomow/Girou).
C++ is a pretty powerful and nice weapon to own, but approach it from the wrong side and it can just become the worst of your nightmares. Assuming that you can understand it just using logic is a wrong approach (and not because your logic is weak, but because C++ is not just logic).
精彩评论