C++ 来自另一个类的switch语句中的static const int导致错误C2051:大小写表达式不是常量
我有一个简单的类,比如C++ 来自另一个类的switch语句中的static const int导致错误C2051:大小写表达式不是常量,c++,compiler-errors,static,switch-statement,syntax-error,C++,Compiler Errors,Static,Switch Statement,Syntax Error,我有一个简单的类,比如 class Person { static const int MALE; // in Person.cpp initialized = 1 static const int FEMALE;//in Person.cpp initialized = 2 }; 在公司类(Company.cpp文件,我有公司类)中,我有带开关的函数 switch(x){// x is int passed as parameter to function case
class Person {
static const int MALE; // in Person.cpp initialized = 1
static const int FEMALE;//in Person.cpp initialized = 2
};
在公司类(Company.cpp文件,我有公司类)中,我有带开关的函数
switch(x){// x is int passed as parameter to function
case Person::MALE:
//do something
break;
case Person::FEMALE:
//do something
break;
}
但当我尝试构建时,我得到了错误错误C2051:case表达式不是常量
,用于上面开关中case的行
当它是常量时有什么问题?按以下方式更改静态数据成员的声明
class Person {
static const int MALE = 1;
static const int FEMALE = 2;
};
编译器必须在编译时知道大小写标签的值。在
case
表达式中使用的值在编译时应该已经知道,因为它们在某种程度上是“硬编码”为二进制代码的。在这里,它们仅在连接阶段指定。解决方案可能如下所示:
// person.h
enum Person { MALE, FEMALE };
常量
不是常量表达式,除非
- 它是整数类型的
const
变量,以前使用文字或其他常量表达式初始化
C++11添加了constexpr
,可与非整数类型的变量一起使用,但对预先初始化的要求仍然适用
您的问题是,在Company.cpp中,此变量尚未初始化。编译器必须假设实际定义涉及运行时计算。例如,编写const int Person::MALE=rand()是完全合法的代码>
或者如果包含Person.cpp
const int Person::MALE = 1;
const int Person::FEMALE = 1;
然后,编译器将不得不拒绝Company.cpp,因为案例不是唯一的。那怎么办?如果有人在Company.cpp被编译之后编辑了Person.cpp会怎么样?C++不是java。使用枚举:
enum Person
{
Person_male = 1,
Person_female = 2
};
根据C++11标准:表达式不是常量
表达式,如果它包含从左值到右值的转换,
除非它适用于“积分或枚举的值”
类型,该类型引用具有前一个
初始化,用常量表达式初始化”。(那里
是一些其他情况,但它们不适用于此处。)注意
“预先初始化”的要求;不仅仅是
变量为常量,但编译器必须能够看到其
初始化
该标准的早期版本在这方面有些模糊
尊重,以及他们字面上的自然解释
say表示您的代码是合法的。这当然是
然而,这并非本意;没有编译器在中实现它
这种方式(因为它通常需要分开
编译时,C++ 11明确地表示这是非法的。对于这样的事情,我建议使用<代码> EnUM < /C> > ----- 1:使它成为<代码> EnUM <代码>将帮助编译器传递代码,但是它只围绕问题而不是OP想要做的:使用<代码>静态const < /> >。C++是不是java,但这并不意味着我们必须在这里使用枚举。不,他不必使用枚举,但这是他试图做的事情的最佳解决方案。回答得好。顺便说一句,这个类和枚举类型在实际意义上有什么区别?@ShijingLv-这个看起来更像Java。没有评论这是否是件好事。@ShijingLv:enum声明定义了一个新类型,可以用作性别变量的类型,例如该函数中的参数x
。这究竟是谁让switch语句编译的?我会说不,但是我离C++编译器太远了,无法测试它。code>case
标签需要编译时常量,但是const
关键字不一定只使变量保持常量readonly@ShijingLv:您可以获取静态常量的地址,但不能获取枚举的地址。这是否会产生影响取决于你的课程。