【问题标题】:Case expression not constant案例表达式不恒定
【发布时间】:2011-12-24 09:22:41
【问题描述】:

我在 switch 语句中收到“case expression not constant”错误。但是,标头为使用的常量提供了定义,构造函数在其初始化列表中为它们提供了初始化。

此外,当我将鼠标悬停在“问题”语句上时,它会将它们标识为常量。

const int ThisClass::EXAMPLE_CONSTANT

error expression must have a constant value

这对我来说似乎有点违反直觉。我做了一些研究,发现了其他人遇到的类似问题。他们被告知所有常量实际上必须在“main”中初始化,这是语言的限制。真的是这样吗?似乎不太可能。

【问题讨论】:

  • 提供演示问题的实际代码。您粘贴的内容并没有真正的帮助。
  • 你用的是什么编译器?真的是 C++ 吗?

标签: c++


【解决方案1】:

您需要一个“真正的”编译时间整数常量。 C++中const表示只读,一个const变量可以 像int y = 0; const int x = y; 一样进行初始化,使x 成为初始化时y 值的只读副本。

使用现代编译器,您可以使用 enums 或 constexprs 来存储 compile-time-constness 的(整体)成员:

class Foo {
public:
    static constexpr int x = 0;
    enum { y = 1 };
};

int main () {
    switch (0) {
    case Foo::x: ;
    case Foo::y: ;
    }
}

【讨论】:

  • constexpr 不会使成员静态。
【解决方案2】:

case 语句需要在编译时必须知道的整数值,这就是这里 constant 的意思。但是在这个意义上,classconst 成员并不是真正的constant。它们只是只读的。

您可以使用enum 代替字段:

class ThisClass
{
    public:

        enum Constants
        {
            EXAMPLE_CONSTANT = 10,
            ANOTHER_CONSTANT = 20
        };    
};

然后你就可以写了,

switch(c)
{
      case ThisClass::EXAMPLE_CONSTANT:
                   //code
                   break;
      case ThisClass::ANOTHER_CONSTANT:
                   //code
                   break;
};

【讨论】:

  • 如果常量不相关,我建议使用未命名的枚举。
【解决方案3】:

case 标签中使用的常量必须是整数常量表达式整数常量表达式必须满足比声明为const的整数对象更严格的要求。

非静态类成员不能在整型常量表达式中使用,因此您尝试执行的操作不会编译。例如,静态类成员可以在整型常量表达式中使用,如果它的初始值设定项在使用时是“可见的”。

【讨论】:

    【解决方案4】:

    这有点乱。在 C++ 中,const 可用于多种用途,例如声明实际常量和声明只读变量。

    如果你声明:

    const int x = 0;
    

    在全局、命名空间或局部范围内,它是一个常量。您可以在需要常量表达式的地方使用它(例如大小写标签或数组大小)。但是,在类范围内或作为函数参数,它只是一个只读变量。

    另外,如果你在类范围内声明:

    static const int x = 0;
    

    这也是一个常数。

    【讨论】:

    • 在函数范围内(即在本地范围内)声明并使用整型常量表达式初始化的 const int 变量本身在 C++ 中形成整型常量表达式。所以在函数范围内,它不仅仅是一个“只读变量”。
    • @AndreyT 哎呀,我的意思是函数参数:) 谢谢。
    【解决方案5】:

    std::map + C++11 lambdas 解决方法

    这个方法允许使用非常量,应该给我们O(1) amortized What is the best way to use a HashMap in C++?

    #include <ctime>
    #include <functional>
    #include <unordered_map>
    #include <iostream>
    
    int main() {
        int result;
        int key0 = std::time(NULL) % 3;
        int key1 = (key0 + 1) % 3;
        int key2 = (key0 + 2) % 3;
        std::unordered_map<int,std::function<void()>> m{
            {key0, [&](){ result = 0; }},
            {key1, [&](){ result = 1; }},
            {key2, [&](){ result = 2; }},
        };
        m[key0]();
        std::cout << key0 << " " << result << std::endl;
        m[key1]();
        std::cout << key1 << " " << result << std::endl;
        m[key2]();
        std::cout << key2 << " " << result << std::endl;
    }
    

    可能的输出:

    1 0
    2 1
    0 2
    

    如果要在类内部使用,请不要忘记静态构建地图,如下所示:Why switch statement cannot be applied on strings?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 2015-08-18
      相关资源
      最近更新 更多