Почему статические константные члены не могут появляться в постоянном выражении типа "switch"
У меня есть следующее объявление некоторых статических константных элементов
.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" не может появляться в константном выражении.
Я прочитал другой файл switch-can not-seem-constant-stuff и не нашел ответа для меня, так как не понимаю, почему те static const unsigned char
не являются постоянным выражением.
Я использую gcc 4.5.
Ответы
Ответ 1
Проблемы, которые вы видите, связаны с тем, что этот
static const unsigned char sInvalid;
не может быть выражением постоянной времени компиляции, поскольку компилятор не знает его значения. Инициализируйте их в заголовке следующим образом:
class MyClass : public MyBase
{
public:
static const unsigned char sInvalid = 0;
...
и он будет работать.
Ответ 2
Значения действительно const
, но они не являются константами времени компиляции.
A switch
условие разрешено во время компиляции, а не во время выполнения. Вы можете инициализировать sInvalid
до любого значения, если только один раз, а switch
никогда не узнает об этом до времени выполнения.
Кажется, что вам лучше использовать enum
вместо констант static
. Помимо того, что он будет работать, он кажется более подходящим по дизайну.
Ответ 3
Вы можете использовать трюк перечисления, чтобы сделать их константами времени компиляции:
class MyClass
{
public:
enum {
sInvalid,
sOutside,
sInside,
//(41 more ...)
};
};
В вашем коде вы все равно можете использовать перечисление для поиска беззнакового char, что-то вроде этого:
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.