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

时间:2010-08-13 16:30:08

标签: c++ types expression switch-statement constants

假设我有一个像这样定义的类“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; }
};

使用代码类的第二类“Master”:

class Master
{
public:
    Code master_code;
};

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

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");

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

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

    case CODE_TWO:
        // ...
        break;

    case CODE_THREE:
        // ...
        break;

    default:
        // ...
}

由于自动类型转换为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:
        // ...
}

以上内容返回完全相同的错误:“'CODE_ONE'不能出现在常量表达式中”除了“'。”不能出现在常量表达式中。“

但这确实有效:

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

    case 2:
        // ...
        break;

    case 3:
        // ...
        break;

    default:
        // ...
}

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

4 个答案:

答案 0 :(得分:6)

switch语句中的标签必须是“整数常量表达式”(§6.4.2/ 2)。积分常数表达式“定义为(§5.19/ 1):

  

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

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

答案 1 :(得分:1)

开关标签必须是编译时常量。在运行时创建CODE_XXX对象之后,您要比较的值才可用。

答案 2 :(得分:0)

switch case语句的case标签应该是编译时常量并且必须是整数。 CODE_ONE,CODE_TWO等不是编译时积分常量。

参见6.4.2 / 2

答案 3 :(得分:0)

CODE_ONE,...等被定义为const的事实并不意味着它们实际上是常量表达式。所有const都是'try'并强制执行这些类实例不会被const定义的规则更改。最后,类(或该结构的结构)实例永远不会被视为完全常量表达式,因为它是一个动态对象。

switch语句需要的是一个“编译时常量表达式”,它对于C ++ 98的所有意图和目的都是一个int文字或枚举值(最后也是int literal)。

C++0x' constexpr会让你做更复杂的事情,比如使用常量函数,但不能用你要求的东西。