c ++结构和const

时间:2010-08-17 07:52:09

标签: c++ visual-c++ winapi struct

好吧,我有结构

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

我有一个开关声明

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;
        }

我得到一个错误,即ball1.BALL_ID不是常数,第二行应该解决这个但是它不知道吗?

3 个答案:

答案 0 :(得分:3)

case标签必须是整数常量表达式 - 它们必须在翻译期间(即在编译时)可评估。在这种情况下,无法在编译时评估BALL_ID。允许不同的ball个对象具有不同的BALL_ID值,因此编译器在翻译期间无法对其进行评估。此外,.(对象的成员解析运算符)不能用于案例标签(即使你确实使BALL_ID static它不适合你)。

我会猜测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;
  }
}

答案 1 :(得分:0)

必须在编译时知道案例标签(基本假设是,switch比在编译时知道值的ifs序列更有效地实现,例如使用跳转表。 const是必需的,但还不够。 ball.BALL_ID是const的东西,在编译时是不知道的,因此不能是案例标签。

答案 2 :(得分:0)

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