Reference-type conversion operators: asking for trouble?
- by Ben
When I compile the following code using g++
class A {};
void foo(A&) {}
int main()
{
foo(A());
return 0;
}
I get the following error messages:
> g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:10: error: invalid initialization of non-const reference of type ‘A&’ from a temporary of type ‘A’
test.cpp:6: error: in passing argument 1 of ‘void foo(A&)’
After some reflection, these errors make plenty of sense to me. A() is just a temporary value, not an assignable location on the stack, so it wouldn't seem to have an address. If it doesn't have an address, then I can't hold a reference to it. Okay, fine.
But wait! If I add the following conversion operator to the class A
class A
{
public:
operator A&() { return *this; }
};
then all is well! My question is whether this even remotely safe. What exactly does this point to when A() is constructed as a temporary value?
I am given some confidence by the fact that
void foo(const A&) {}
can accept temporary values according to g++ and all other compilers I've used. The const keyword can always be cast away, so it would surprise me if there were any actual semantic differences between a const A& parameter and an A& parameter. So I guess that's another way of asking my question: why is a const reference to a temporary value considered safe by the compiler whereas a non-const reference is not?