I\'ve been looking into this for a few hours, to no avail. Basically I have
struct rectangle {
int x, y, w, h;
};
rectangle player::RegionCoordinates() // R
Since IsCollision
takes a rectangle *
and you are taking the address of the result here:
if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates()))
You most likely are returning a rectangle
back from RegionCoordinates()
which is a temporary variable since it will disappear after the if
statement is done. If you assign the result of RegionCoordinates()
to a variable then it will no longer be a temporary and you can then take the address of it:
rectangle r1 = player1.RegionCoordinates() ;
rectangle r2 = stick1.RegionCoordinates() ;
if (IsCollision(&r1, &r2))
Alternatively you could take the parameters as const
references which would be the more C++ way of doing it:
bool IsCollision (const rectangle &r1, const rectangle &r2)
Given the kind of error you are getting, I must assume RegionCoordinates()
is returning an object by value, thus causing the creation of a temporary, and you are taking the address of that temporary.
The address-of operator requires an lvalue as its operand, but you are applying it to an rvalue (temporaries are rvalues).
You could do this (if you are not using C++11, replace auto
with the type returned by 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);
}
Alternatively, you can change IsCollision
so that it accepts references rather than pointers, as suggested by Angew in his answer.
RegionCoordinates()
returns an object by value. This means a call to RegionCoordinates()
returns a temporary instance of rectangle
. As the error says, you're trying to take the address of this temporary object, which is not legal in C++.
Why does IsCollision()
take pointers anyway? It would be more natural to take its parameters by const reference:
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);
}