2010-08-17 85 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標籤需要一個常量表達式。