为什么std :: bitset :: at()抛出out_of_range?

时间:2011-09-24 04:27:57

标签: c++ algorithm debugging exception stl

这让我困扰了几个小时,因为我在数学或代码中看不到任何问题。 (尽管盯着它看,并一遍又一遍地努力确定。)我希望大家可以帮助我,这是我的代码:

#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; ::在()

此时zyx的值分别为100

你能告诉我这里发生了什么导致这个例外吗? 提前谢谢!

2 个答案:

答案 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) )