14

我有一些静态常量成员的以下声明

。H

class MyClass : public MyBase
{
public:
    static const unsigned char sInvalid;
    static const unsigned char sOutside;
    static const unsigned char sInside;
    //(41 more ...)
}

.cpp

const unsigned char MyClass::sInvalid = 0;
const unsigned char MyClass::sOutside = 1;
const unsigned char MyClass::sInside = 2;
//and so on

在某些时候,我想在开关中使用这些值,例如:

unsigned char value;
...
switch(value) {
    case MyClass::sInvalid : /*Do some ;*/ break;
    case MyClass::sOutside : /*Do some ;*/ break;
    ...
}

但我收到以下编译器错误:错误:'MyClass::sInvalid' cannot appear in a constant-expression

我已经阅读了其他 switch-cannot-appear-constant-stuff 并没有为我找到答案,因为我不明白为什么这些static const unsigned char不是常量表达式。

我正在使用 gcc 4.5。

4

3 回答 3

19

你看到的问题是由于这个事实

static const unsigned char sInvalid;

不能是编译时常量表达式,因为编译器不知道它的值。像这样在标题中初始化它们:

class MyClass : public MyBase
{
public:
    static const unsigned char sInvalid = 0;
    ...

它会起作用。

于 2012-05-16T13:06:35.993 回答
9

这些值确实是const,但它们不是编译时常量

条件在switch编译时解决,而不是在运行时解决。您可以初始化sInvalid为任何值,只要它只有一次,并且switch直到运行时才会知道它。

似乎您最好使用enums 而不是static常量。除了它可以工作之外,它似乎更适合设计。

于 2012-05-16T13:04:54.760 回答
2

您可以使用枚举技巧使它们成为编译时常量:

class MyClass 
{
public:
    enum {
        sInvalid,
        sOutside,
        sInside,
        //(41 more ...)
    };
};

在您的代码中,您仍然可以使用枚举来分配无符号字符,如下所示:

int main(int argc, char *argv[])
{
    unsigned char buf[32];
    buf[0] = MyClass::sInvalid; //int to unsigned char
    return buf[0]; //Cast back to int (and avoid a warning a -Wall)
}

MyClass::sInvalid在您的 swith 语句中使用。

于 2012-05-16T13:35:33.923 回答