这让我困扰了几个小时,因为我在数学或代码中看不到任何问题。 (尽管盯着它看,并一遍又一遍地努力确定。)我希望大家可以帮助我,这是我的代码:
#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循环完全运行它们(总共16次传递。)但是,一旦z
变为1,那就是从内部抛出异常的时候的std ::位集&LT; 64&GT; ::在()
此时z
,y
,x
的值分别为1
,0
,0
。
你能告诉我这里发生了什么导致这个例外吗? 提前谢谢!
答案 0 :(得分: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
将不正确!你需要这样做:
#define SOLVE_POSITION(x, y, z) ( (z)*16 + (y)*4 + (x) )
以便它正确扩展为:
( (3-x)*16 + (y)*4 + (3-z) )
正如所料。
答案 1 :(得分: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) )