How come a non-const reference cannot bind to a temporary object?

From this Visual C++ blog article about rvalue references:

… C++ doesn’t want you to accidentally
modify temporaries, but directly
calling a non-const member function on
a modifiable rvalue is explicit, so
it’s allowed …

Basically, you shouldn’t try to modify temporaries for the very reason that they are temporary objects and will die any moment now. The reason you are allowed to call non-const methods is that, well, you are welcome to do some “stupid” things as long as you know what you are doing and you are explicit about it (like, using reinterpret_cast). But if you bind a temporary to a non-const reference, you can keep passing it around “forever” just to have your manipulation of the object disappear, because somewhere along the way you completely forgot this was a temporary.

If I were you, I would rethink the design of my functions. Why is g() accepting reference, does it modify the parameter? If no, make it const reference, if yes, why do you try to pass temporary to it, don’t you care it’s a temporary you are modifying? Why is getx() returning temporary anyway? If you share with us your real scenario and what you are trying to accomplish, you may get some good suggestions on how to do it.

Going against the language and fooling the compiler rarely solves problems – usually it creates problems.

Edit: Addressing questions in comment:
1) X& x = getx().ref(); // OK when will x die? – I don’t know and I don’t care, because this is exactly what I mean by “going against the language”. The language says “temporaries die at the end of the statement, unless they are bound to const reference, in which case they die when the reference goes out of scope”. Applying that rule, it seems x is already dead at the beginning of the next statement, since it’s not bound to const reference (the compiler doesn’t know what ref() returns). This is just a guess however.

2) I stated the purpose clearly: you are not allowed to modify temporaries, because it just does not make sense (ignoring C++0x rvalue references). The question “then why am I allowed to call non-const members?” is a good one, but I don’t have better answer than the one I already stated above.

3) Well, if I’m right about x in X& x = getx().ref(); dying at the end of the statement, the problems are obvious.

Anyway, based on your question and comments I don’t think even these extra answers will satisfy you. Here is a final attempt/summary: The C++ committee decided it doesn’t make sense to modify temporaries, therefore, they disallowed binding to non-const references. May be some compiler implementation or historic issues were also involved, I don’t know. Then, some specific case emerged, and it was decided that against all odds, they will still allow direct modification through calling non-const method. But that’s an exception – you are generally not allowed to modify temporaries. Yes, C++ is often that weird.

Leave a Comment