简体   繁体   English

来自另一个类的switch语句中的static const int导致错误C2051:case表达式不是常量

[英]static const int in switch statement from another class cause error C2051: case expression not constant

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 在公司类(Company.cpp文件中,我有公司类)我有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 ? 但是当我尝试构建时,我得到了错误error C2051: case expression not constant在上面的开关中, error C2051: case expression not constant对于行error C2051: case expression not constant的当它是const时有什么问题?

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. 编译器必须在编译期间知道案例标签的值。

A const is not a constant expression unless 除非, const不是常量表达式

  • It is a const variable of integral type, previously initialized with a literal or other constant expression. 它是整数类型的const变量, 之前使用文字或其他常量表达式初始化。

C++11 adds constexpr , which can be used with variables of non-integral type, but the requirement for a prior initialization still applies. C ++ 11添加了constexpr ,它可以与非整数类型的变量一起使用,但是仍然需要先前的初始化。

Your problem is that in Company.cpp, this variable has not been initialized. 您的问题是在Company.cpp中,此变量尚未初始化。 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(); 例如,编写const int Person::MALE = rand();

Or if Person.cpp contained 或者如果包含Person.cpp

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. 然后编译器必须拒绝Company.cpp,因为这些情况不是唯一的。 How would that work? 那会怎么样? What if someone edited Person.cpp after Company.cpp was already compiled? 如果有人在编译了Company.cpp之后编辑了Person.cpp怎么办?

Values used in case expressions should be already known on compile-time, because they are somewhat "hardcoded" into binary code. case表达式中使用的值应该在编译时已知,因为它们在某种程度上被“硬编码”为二进制代码。 And here they are specified only at a linkage phase. 在这里,它们仅在链接阶段指定。 Probably the solution might be following: 可能解决方案可能如下:

// person.h
enum Person { MALE, FEMALE };

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". 根据C ++ 11标准:如果表达式包含左值到右值的转换,则表达式不是常量表达式, 除非它应用于“带有非易失性const对象的整数或枚举类型的glvalue”前面的初始化,用常量表达式初始化“。 (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. 不仅变量必须是const,而且编译器必须能够看到它的初始化。

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. 没有编译器以这种方式实现它(因为它通常需要打破单独的编译),而C ++ 11清楚地说这是非法的。

C++ is not java. C ++不是java。 Use enums: 使用枚举:

enum Person
{
  Person_male = 1,
  Person_female = 2
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM