C ++错误:'x'不是常量表达式,如何修复?

时间:2016-04-16 02:02:11

标签: c++ compiler-errors logic constexpr

简而言之,这是一个最小的例子:

struct C {
    const int X = 2;
    int y = 2;
};
void f(C* x) {
    switch(x->y) {
        case x->X: printf("%d", 42); break;
        case 123: printf("foo");
    }
}
int main()
{
    C c;
    f(&c);
    return 0;
}

为什么编译器会抱怨error: 'x' is not a constant expression以及如何解决它?

4 个答案:

答案 0 :(得分:6)

switch内的案例标签只接受编译时常量表达式。 x->X 不是一个常量表达式;因此它不能用作case标签。

switch语句替换为if以解决此问题:

if (x->y == x->X) {
    printf("%d", 42);
} else if (x->y == 123) {
    printf("foo");
}

答案 1 :(得分:0)

在main中,您声明一个C的实例并将其传递给f。根据f的定义,它不能保证c不会被改变 - 并且main无法验证它。 我认为f必须是f(C * const x);

答案 2 :(得分:0)

给定代码(模数格式化)

struct C
{
    int const x = 2;
    int y = 2;
};

......意思是:

struct C
{
    int const x;
    int y;

    C(): x( 2 ), y( 2 ) {}
};

...即成员由每个构造函数初始化。

您甚至可以在用户定义的构造函数中覆盖该初始化:

struct S
{
    int const x = 2;

    S(): x( 3 ) {}
};

此处每个实例x都是3。

所以x不是编译时常量。这是一个非常适合的运行时间。因此,它不能用作case中的switch标签,因为case标签必须是编译时已知的值。反过来因为switch构造被设计为在值范围允许的情况下有效地实现为简单数组索引(计算跳转)。

一个简单的解决方法是将相关值定义为编译时常量。作为类中的staticenum值。或者在课外。

另一种可能的解决方法是使用if - else阶梯代替switch

答案 3 :(得分:0)

大小写接受常量表达式,如2或' a'。和Const只定义一个不变的变体。