2010-08-17 84 views
2

确定好我有结构C++结构和const

struct balls { 
    balls(UINT_PTR const &val) : BALL_ID(val){} 
    int Ex; 
    int Ey; 
    const UINT_PTR BALL_ID; 
}; 
balls ball1(0x1); 

和我有一个switch语句

switch(wParam) 
     { 
     case ball1.BALL_ID: 
       if(ball1.Ex<300) 
       { 
        ball1.Ex++; 
       } 
       else 
       { 
        KillTimer(hWnd, ball1.BALL_ID); 
       } 
       InvalidateRect(hWnd, rect, false); 
       break; 
     case SCORECOUNTER_ID: 
       if(life==0) 
       { 
        if(scorecounter<1000) 
        { 
         scorecounter+=100; 
         _swprintf(str, _T("Score: %d"), scorecounter); 
         InvalidateRect(hWnd, rect, false); 
        } 
        else 
        { 
         _swprintf(level, _T("Level: %d"), 2); 
         InvalidateRect(hWnd, rect, false); 
        } 
       } 
      break; 
     } 

我得到一个错误thatball1.BALL_ID不是恒定的第二行应该解决了这一点,但它没有任何想法?

回答

3

case标签必须为积分常量表达式 - 它们在翻译过程中(即编译时)必须是可评估的。在这种情况下,BALL_ID无法在编译时进行评估。允许不同的ball对象具有不同的BALL_ID值,因此编译器无法在翻译过程中对其进行评估。进一步,.(对象的成员分辨率运算符)不能用于案例标签(即使您确实制作了BALL_IDstatic它也不适用于您)。

我会冒险猜测SCORECOUNTER_ID是一个宏/ static const int,因此可以由编译器进行评估。

您可以使用命名空间范围enumint来解决此问题。 E.g:

struct s { 
s(const int t) : x(t) {} 
const int x; 
}; 

namespace s2 { 
const int val = 42; 
} 

int main() { 
s ss(4); 
int val = 42; 
switch (val) { 
    case s2::val: 
    break; 
    } 
} 
+0

那么我该如何解决它? – Ramilol 2010-08-17 08:10:01

+0

使用if(),可能。 – 2010-08-17 08:15:36

+0

...为什么当然是,除非OP需要坚持'switch'! – dirkgently 2010-08-17 08:17:43

0

情况下标签具有在编译时是已知的(基本假设是,switch比IFS知道在编译时的值的序列来实现更有效地使用跳转表例如)。 const是必要的,但并不足够。 ball.BALL_ID是const这是在编译时不知道的东西,所以不能是一个case标签。

0

不是每个整型常量变量都是一个常量表达式。 switch语句的case标签需要一个常量表达式。