Reputation: 11562
I have one simple class like
class Person {
static const int MALE; // in Person.cpp initialized = 1
static const int FEMALE;//in Person.cpp initialized = 2
};
In Company class (Company.cpp file, I have company class) I have function with switch
switch(x){// x is int passed as parameter to function
case Person::MALE:
//do something
break;
case Person::FEMALE:
//do something
break;
}
but when I try to build I got error error C2051: case expression not constant
for lines in case in switch above
What is a problem when it is a const ?
Upvotes: 3
Views: 3381
Reputation: 283793
A const
is not a constant expression unless
const
variable of integral type, previously initialized with a literal or other constant expression.C++11 adds constexpr
, which can be used with variables of non-integral type, but the requirement for a prior initialization still applies.
Your problem is that in Company.cpp, this variable has not been initialized. The compiler will have to assume that the actual definition involves a runtime calculation. For example, it is perfectly legal to write const int Person::MALE = rand();
Or if Person.cpp contained
const int Person::MALE = 1;
const int Person::FEMALE = 1;
then the compiler would have to reject Company.cpp because the cases are not unique. How would that work? What if someone edited Person.cpp after Company.cpp was already compiled?
Upvotes: 3
Reputation: 154007
According to the C++11 standard: an expression is not a constant expression if it contains an lvalue-to-rvalue conversion, unless it is applied to "a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression". (There are some other cases, but they don't apply here.) Note the requirement for a "preceding initialization"; not only must the variable be const, but the compiler must be able to see its initialization.
Earlier versions of the standard were somewhat vague in this regard, and the natural interpretation of what they literally say would suggest that your code be legal. This was certainly not what was intended, however; no compiler implemented it in this way (since it would generally require breaking separate compilation), and C++11 clearly says that this is illegal.
Upvotes: 1
Reputation: 672
C++ is not java. Use enums:
enum Person
{
Person_male = 1,
Person_female = 2
};
Upvotes: 0
Reputation: 4435
Values used in case
expressions should be already known on compile-time, because they are somewhat "hardcoded" into binary code. And here they are specified only at a linkage phase. Probably the solution might be following:
// person.h
enum Person { MALE, FEMALE };
Upvotes: 1
Reputation: 311088
Change the declarations of static data members the following way
class Person {
static const int MALE = 1;
static const int FEMALE = 2;
};
The compiler must know the values of case labels during the compilation time.
Upvotes: 10