Reputation: 7769
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 as
int 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?
Upvotes: 4
Views: 1521
Reputation: 132994
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)
Class rvalues can have cv-qualified types; non-class rvalues always have cv-unqualified types. Rvalues shall always have complete types or the void type; in addition to these types, lvalues can also have incomplete types.
Upvotes: 6