Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 来自另一个类的switch语句中的static const int导致错误C2051:大小写表达式不是常量_C++_Compiler Errors_Static_Switch Statement_Syntax Error - Fatal编程技术网

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:您可以获取
静态常量的地址,但不能获取
枚举的地址。这是否会产生影响取决于你的课程。