【问题标题】:Why is std::bitset::at() throwing out_of_range?为什么 std::bitset::at() 会抛出 out_of_range?
【发布时间】:2011-09-24 04:27:56
【问题描述】:

这让我困惑了几个小时,因为我在数学或代码中看不到任何问题。 (尽管盯着它并一遍又一遍地解决它以确保。)我希望你们能帮助我,这是我的代码:

#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::bitset 中抛出异常::at().

此时zyx的值分别为100

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

【问题讨论】:

    标签: c++ algorithm debugging exception stl


    【解决方案1】:

    宏!你必须非常小心:

    你定义:

    #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) )
    

    正如预期的那样。

    【讨论】:

    • ...哇,我觉得我直接走进了一个陷阱!谢谢,终于可以用了!
    • @Clairvoire:问为什么你甚至会在这里使用宏,因为所有的机会都搞砸了。
    • 好吧,加上括号,它工作正常。如果我避免所有有可能搞砸的事情,我就不会成为 C++ 程序员。 :P
    【解决方案2】:

    宏使用文本替换,您实际上是在告诉编译器

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

    【讨论】:

    • 这就是为什么内联函数经常被推荐作为类函数宏的替代品。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 2012-01-16
    • 2013-02-18
    • 1970-01-01
    相关资源
    最近更新 更多