2011-09-24 47 views
1

現在,這讓我難過了幾個小時,因爲我在數學或代碼中看不到任何問題。 (Dispite盯着它和工作它一遍又一遍,以確保)我希望你們這些人能幫助我,這裏是我的代碼:爲什麼std :: bitset :: at()拋出out_of_range?

#define SOLVE_POSITION(x, y, z) (z*16 + y*4 + x) 

std::bitset<64> block; 
block.reset(); 

for(int z = 0; z < 4; ++z){ 
    for(int y = 0; y < 4; ++y){ 
     for(int x = 0; x < 4; ++x){ 

      if(block.at(SOLVE_POSITION(3-x, y, 3-z))){ //<-- call to at() throws 'out_of_range' 

       // do stuff 
      }; 
     }; 
    }; 
}; 

隨着z爲0,這兩個最內部的for循環然後,一旦z變爲1,那麼當std :: bitset < 64> :: at()時拋出異常。

zyx的值是分別100的那一刻。

你能告訴我這裏發生了什麼事情導致這個異常嗎? 在此先感謝!

回答

7

宏!你必須要非常小心這一點:

您定義:

#define SOLVE_POSITION(x, y, z) (z*16 + y*4 + x) 

所以當你:

SOLVE_POSITION(3-x, y, 3-z) 

它擴展爲:

(3-x*16 + y*4 + 3-z) 

而且由於運營商優先,3-x*16將不正確!你需要做的:如預期

((3-x)*16 + (y)*4 + (3-z)) 

#define SOLVE_POSITION(x, y, z) ((z)*16 + (y)*4 + (x)) 

以便正確擴展到。

+0

......哇,我覺得就像我直接走進了一個陷阱!謝謝,它終於現在工作! –

+1

@Clairvoire:問題是爲什麼你會在這裏使用一個宏,因爲它有所有的機會搞砸它。 –

+0

那麼,用括號,它工作正常。如果我避免了所有可能會搞砸的事情,我就不會成爲C++程序員。 :P –

1

宏使用文本替換,你就相當於告訴編譯器

SOLVE_POSITION(3-x, y, 3-z) => SOLVE_POSITION(3-z*16 + y*4 + 3-x) 

爲了解決這個問題,一定要圍繞你的宏參數用括號:

#define SOLVE_POSITION(x, y, z) ((z)*16 + (y)*4 + (x)) 
+1

這就是爲什麼內聯函數經常被推薦用來替代功能宏的原因。 – han

相關問題