This is a followup to this question.
A 2002 paper on the function forwarding problem in C++ makes the following observation:
This is the method currently employed
by Boost.Bind and Boost.Lambda:template<class A1, class A2, class A3> void f(A1 & a1, A2 & a2, A3 & a3) { return g(a1, a2, a3); }Its main deficiency is that it cannot
forward a non-const rvalue. The
argument deduction creates a non-const
reference, and the reference cannot
bind to the argument. This makes
innocent examples asint main() { f(1, 2, 3); }fail (violates C1).
I see that the call fails, but is the explanation correct? Are not the literals 1, 2, 3 const rvalues?
Are not the literals 1, 2, 3 const rvalues?No, they are just rvalues of type int. According to the C++ standard, rvalues of primitive types cannot be const-qualified.
The call fails because they are rvalues – non-const references cannot be bound to rvalues.
The call would be OK if the functions took
const A1 &, const A2&, const A3&, but in this case the function wouldn’t be able to modify the arguments.Edit: Reference to my first statement from the C++ 2003 standard : (3.10.9)