TITLE: why disallow non-const references bound to rvalues PROBLEM: davew@trigati.cs.haverford.edu (David G. Wonnacott) I am looking for an explanation for the rationale behind the decision of the standards committee to disallow the binding of a non-const reference to an rvalue. RESPONSE: clamage@Eng.sun.com (Steve Clamage), 28 Mar 96 The basic reason is that it usually is an error. If you have a non-const, (rather than a const) reference, the presumption is that you are likely to modify the referenced object. Modifying an rvalue is not likely to be what was intended. Two examples: double& rd = 2.0; // #1 In #1, we have a reference to ... what? "2.0" isn't an object, it is a value. What should it mean to assign to rd? Why not write double rd = 2.0; // rd is now an object instead? If you don't intend to assign to rd, make it a reference to const. const double& rd = 2.0; // OK This case is rather minor. The main problem shows up in the next example. void f(double& rd); int k = ...; f(k); // #2 In #2, we should assume that function f is going to modify its actual argument. But the actual argument has type int. An int can be converted to a double, so the compiler could create a temp double, and pass a reference to the temp. If f is declared to take a const reference, that is what happens. That can't cause a problem, since the value can't be changed by function f. But if f assigns to its non-const actual argument, the assumption is that the actual argument is changed; that won't happen in this case. The value of k is unaffected by anything that happens in f. If you mean to allow passing an int to f, you have three choices: pass by value instead of reference, or declare the formal parameter to be a reference to a const double, or create an explicit variable of the right type and initialize it with the value of k first: double t = k; f(t); // OK Any of these approaches makes it clear that k is not going to be changed. For simplicity, I have shown examples with int and double, which will almost always have different sizes and representations. The arguments are even stronger with class types. Please also note that when I say things like "can't happen", I mean in a well-formed program. Yes, there are times when you would like to be able to bind an rvalue to a non-const reference, since the only things you care about are sure to happen anyway. For example, given a class T: T f1(); // f1 returns a T rvalue f1().foo(); // ok only if foo is a const member function of T Sometimes you don't care about the effects of foo on the object here, and you only want the external side-effects of foo. I believe the C++ committee looked for ways to allow this binding of an rvalue to a non-const reference in cases where the results were what was intended, but failed to find a good way to define those cases.