简而言之,这是一个最小的例子:
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
以及如何解决它?
答案 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
构造被设计为在值范围允许的情况下有效地实现为简单数组索引(计算跳转)。
一个简单的解决方法是将相关值定义为编译时常量。作为类中的static
或enum
值。或者在课外。
另一种可能的解决方法是使用if
- else
阶梯代替switch
。
答案 3 :(得分:0)
大小写接受常量表达式,如2或' a'。和Const只定义一个不变的变体。