ThomasMcLeod
ThomasMcLeod

Reputation: 7769

C++ Perfect Function Forwarding

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

Answers (1)

Armen Tsirunyan
Armen Tsirunyan

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

Related Questions