我能在case语句中使用数组吗?

3
我希望在C++中的switch/case语句中使用一个const int数组,这是否可能?到目前为止,我尝试了以下内容:
int main()
{
    int const tab[3] = {1,2,3};
    int value(2);
    switch(value)
    {
        case tab[1]:
            cout << "result is: " << tab[0]<< endl;
    }
    return 0;
}

然而编译器不断告诉我:
.../main.cpp|11|error: the value of ‘tab’ is not usable in a constant expression

我将我的数组声明为 "int const",这不足够吗?
2个回答

6
每个case语句必须使用一个常量表达式,定义如下:

除非按照抽象机器的规则(1.9),条件表达式e的计算将计算以下表达式之一,否则e是一个核心常量表达式

  • [...]
  • 左值到右值转换(4.1),除非它应用于:
    • 整数或枚举类型的非易失性glvalue,该glvalue引用具有前置初始化、用常量表达式初始化的非易失性const对象[注:字符串字面值(2.14.5)对应于这样的对象数组。—结尾注释],或
    • 引用具有constexpr定义的非易变子对象的非易变性glvalue,或者引用这样一个对象的非易变性子对象,或
    • 字面类型的非易变性glvalue,其引用在e的评估中开始了对象的生命周期;
  • [...]
你的情况是一个左值到右值转换,但是这三个要点都不适用于tab[1],因此tab[1]不是一个核心常量表达式。然而,第二个子要点给了我们一个提示:如果对象是用constexpr定义的,会怎样呢!这将使tab[1]成为一个常量表达式,因此,这个代码可以编译:
constexpr int tab[3] = {1,2,3};
int value(2);
switch(value)
{
    case tab[1]:
        cout << "result is: " << tab[0]<< endl;
}

const并不会使对象成为常量表达式,它只是使其无法修改。需要注意的是以下代码是完全有效的:

int x;
cin >> x;
const int y = x; // obviously, y can't be a constant expression

为什么l.t.r条件的第一个项目不适用? - David G
1
@0x499602D2 tab 不是整数或枚举类型。如果它是 const int tab = 1;,你可以使用 case tab - Barry
那么转换应用于 tab 而不是 tab[1] - David G
@0x499602D2:它们都必须被转换。如果任何表达式违反条件,则适用规则。全表达式tab[1]是整数类型并不足够,因为评估子表达式tab仍需要一个rvalue转换,并且抽象机器必须评估tab以便评估tab[1] - Steve Jessop

2

你不需要 const, 而是需要 constexpr。使用以下代码进行重写:

int main()
{
    constexpr int tab[3] = {1,2,3};
    int value(2);
    switch(value)
    {
        case tab[1]:
            cout << "result is: " << tab[0]<< endl;
    }
    return 0;
}

由于您需要在编译时获取tab的值,因此它应该是一个constexpr表达式。此外,每个case语句都需要常量表达式,而不是常量值。使用const会使其成为常量值,而constexpr会使其成为常量表达式


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接