为什么我不能在开关/外壳中使用无符号短路?

hua*_*n68 4 c c++

我有两个静态成员声明ClsA,如下所示:

class ClsA {
public:
   static unsigned short m_var1;
   static unsigned short m_var2;
};

unsigned short ClsA::m_var1 = 1001;
unsigned short ClsA::m_var2 = 1002;
Run Code Online (Sandbox Code Playgroud)

ClsB,我使用这样的静态成员声明ClsA:

unsigned short var1; // assume var1 is declare/use some where in the code.

switch( var1 ) {
case ClsA::m_var1:  // Error: cannot appear in a constant-expression
   break;

case ClsB::m_var2:  // Error: cannot appear in a constant-expression
   break;
}
Run Code Online (Sandbox Code Playgroud)

如果我在switch语句中使用它,为什么会出现错误?如果我在if语句中使用它,则没有错误.

Mic*_*kis 11

C++要求case使用常量表达式作为其参数.那是什么意思?这意味着在常量表达式中唯一合法的操作数是:

  • 字面
  • 枚举常数
  • 声明为的值const使用常量表达式初始化
  • sizeof 表达式

在您的情况下,如果您将静态成员声明为const,并在使用整型常量表达式声明时初始化它们,则可以在switch-case语句中使用它们.例如,

class ClsA {
    public:
        static const unsigned short m_var1 = 13;
        static const unsigned short m_var2 = 42;
};
Run Code Online (Sandbox Code Playgroud)

如果,另一方面,你坚持开关上的变量,以避免多个if-else if语句,我建议使用跳转表(它也被称为查找表).


Ste*_*fan 10

尝试

static const unsigned short m_var1;

  • 如果您想了解其中的区别:`switch`需要编译时常量.`if`对运行时值感到满意. (7认同)
  • @Steve:修改物理`const`对象已经是UB - 做**是一个bug. (2认同)
  • @Georg - 我在这里提出的观点是,"未定义的行为"并不意味着您不必考虑可能,偶然或故意的情况.讨论旨在减轻这些事情的编程实践的利弊是合理的,并且没有帮助人们仅仅因为"那是未定义的 - 已经存在一个错误,所以这是无意义的"而拒绝整个想法,忽略了这个事实.避免对编译器无法检测到的错误的敏感性是重点. (2认同)