Ошибка: получение адреса временного [-fpermissive]

Я искал это несколько часов, но безрезультатно. В основном у меня есть

struct rectangle {
int x, y, w, h;
};

rectangle player::RegionCoordinates() // Region Coord
{
rectangle temp;
temp.x = colRegion.x + coordinates.x;
temp.w = colRegion.w;
temp.y = colRegion.y + coordinates.y;
temp.h = colRegion.h;

return temp;
}

// Collision detect function
bool IsCollision (rectangle * r1, rectangle * r2)
{
if (r1->x < r2->x + r2->w &&
r1->x + r1->w > r2->x &&
r1->y < r2->y + r2->h &&
r1->y + r1->h > r2->y)
{
return true;
}
return false;
}

//blah blah main while loop
if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates())) //ERROR
{
player1.score+=10;
stick1.x = rand() % 600+1;
stick1.y = rand() % 400+1;
play_sample(pickup,128,128,1000,false);
}

Есть идеи? Я уверен, что это что-то действительно очевидное, но для жизни я не могу понять это.

10

Решение

RegionCoordinates() возвращает объект по значению. Это означает призыв к RegionCoordinates() возвращает временный экземпляр rectangle, Как говорится в сообщении об ошибке, вы пытаетесь получить адрес этого временного объекта, что недопустимо в C ++.

Почему IsCollision() взять указатели в любом случае? Было бы более естественно взять его параметры по константной ссылке:

bool IsCollision (const rectangle &r1, const rectangle &r2) {
if (r1.x < r2.x + r2.w &&
r1.x + r1.w > r2.x &&
r1.y < r2.y + r2.h &&
r1.y + r1.h > r2.y) {
return true;
}
return false;
}
//blah blah main while loop
if (IsCollision(player1.RegionCoordinates(), stick1.RegionCoordinates())) //no error any more
{
player1.score+=10;
stick1.x = rand() % 600+1;
stick1.y = rand() % 400+1;
play_sample(pickup,128,128,1000,false);
}
14

Другие решения

поскольку IsCollision занимает rectangle * и вы берете адрес результата здесь:

if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates()))

Вы, скорее всего, возвращаете rectangle обратно из RegionCoordinates() которая является временной переменной, так как она исчезнет после if заявление сделано. Если вы назначите результат RegionCoordinates() к переменной, то она больше не будет временной, и вы можете взять ее адрес:

rectangle r1 = player1.RegionCoordinates() ;
rectangle r2 = stick1.RegionCoordinates() ;
if (IsCollision(&r1, &r2))

В качестве альтернативы вы можете принять параметры как const ссылки, которые будут более C ++ способ сделать это:

bool IsCollision (const rectangle &r1, const rectangle  &r2)
4

Учитывая вид ошибки, которую вы получаете, я должен предположить, RegionCoordinates() возвращает объект по значению, вызывая тем самым создание временный, и вы берете адрес этого временного.

Адрес оператора требует именующий как его операнд, но вы применяете его к Rvalue (временные rvalues).

Вы можете сделать это (если вы не используете C ++ 11, замените auto с типом, возвращаемым RegionCoordinates):

auto rcPlayer1 = player1.RegionCoordinates();
auto rcStick1 = player1.RegionCoordinates();
if (IsCollision(&rcPlayer1, &rcStick1)) //ERROR
{
player1.score+=10;
stick1.x = rand() % 600+1;
stick1.y = rand() % 400+1;
play_sample(pickup,128,128,1000,false);
}

Кроме того, вы можете изменить IsCollision так что он принимает Рекомендации а не указатели, как предложено Angew в своем ответе.

1