在switch语句中,期望的常量表达式失败

Oys*_*ein 2 c++ types expression constants switch-statement

假设我有一个像这样定义的类"Code",用户指定的类型转换为int:

class Code
{
public:    
    int code;
    std::string description;

    Code (const int c, const std::string& d) : code(c), description(d) { ; }

    operator int() const { return code; }
};
Run Code Online (Sandbox Code Playgroud)

使用代码类的第二类"Master":

class Master
{
public:
    Code master_code;
};
Run Code Online (Sandbox Code Playgroud)

以及一堆预先指定的代码,如下所示:

const Code CODE_ONE    (1, "This is code one");
const Code CODE_TWO    (2, "This is code two");
const Code CODE_THREE  (3, "This is code three");
Run Code Online (Sandbox Code Playgroud)

有人会认为(即我认为)可以像这样使用它:

Master master_obj;
switch (master_obj.master_code)
{
    case CODE_ONE:
        // ...
        break;

    case CODE_TWO:
        // ...
        break;

    case CODE_THREE:
        // ...
        break;

    default:
        // ...
}
Run Code Online (Sandbox Code Playgroud)

由于自动类型转换为int,但显然并非如此.GCC告诉我CODE_ONE,CODE_TWO和CODE_THREE"不能出现在常量表达式中".

顺便说一句,这也不起作用:

Master master_obj;
switch (master_obj.master_code)
{
    case CODE_ONE.code:
        // ...
        break;

    case CODE_TWO.code:
        // ...
        break;

    case CODE_THREE.code:
        // ...
        break;

    default:
        // ...
}
Run Code Online (Sandbox Code Playgroud)

上面返回完全相同的错误:"'CODE_ONE'不能出现在常量表达式中"除了"'." 不能出现在常量表达式中".

但这确实有效:

Master master_obj;
switch (master_obj.master_code)
{
    case 1:
        // ...
        break;

    case 2:
        // ...
        break;

    case 3:
        // ...
        break;

    default:
        // ...
}
Run Code Online (Sandbox Code Playgroud)

那么CODE_ONE等不能被解析为常量表达式?这看起来很奇怪......或者我做错了什么?

Jer*_*fin 6

switch语句中的标签必须是"整数常量表达式"(§6.4.2/ 2).一个整数常量表达式"定义为(§5.19/ 1):

整数常量表达式只能包含文字(2.13),枚举器,常量变量或使用常量表达式(8.5)初始化的整数或枚举类型的静态数据成员,整数或枚举类型的非类型模板参数以及sizeof表达式.浮动文字(2.13.3)只有在转换为整数或枚举类型时才会出现.只能使用转换为整数或枚举类型的转换.特别是,除了sizeof表达式之外,不应使用函数,类对象,指针或引用,并且不应使用赋值,递增,递减,函数调用或逗号运算符.

因此,您不能进行函数调用(包括转换函数),并且数据成员必须是静态的(您的数据成员不是).

  • @oystein:我应该补充一点,C++ 0x确实扩展了常量表达式的想法.它添加了`constexpr`,你可以用来将事物标记为常量表达式,所以使用类似`int constexpr f(){return 1; 你可以使用`f()`作为常量表达式. (2认同)