Почему std :: bitset :: at () выбрасывает out_of_range? - PullRequest
1 голос
/ 24 сентября 2011

Это поставило меня в тупик на несколько часов, так как я не вижу проблем в математике или коде.(Несмотря на то, что я смотрю на него и разрабатываю его снова и снова, чтобы быть уверенным.) Я надеюсь, что вы, ребята, можете мне помочь, вот мой код:

#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 <64> :: at ().

Значения z, y, x соответственно 1, 0, 0 в данный момент.

Можете ли вы сказать мне, что происходит здесь, чтобы вызватьэто исключение?Заранее спасибо!

Ответы [ 2 ]

7 голосов
/ 24 сентября 2011

Макросы!Вы должны быть очень осторожны с этим:

Вы определяете:

#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 голос
/ 24 сентября 2011

Макросы используют подстановку текста, вы фактически говорите компилятору

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) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...