This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

688. reference_wrapper, cref unsafe, allow binding to rvalues

Section: 22.10.6.2 [refwrap.const] Status: C++11 Submitter: Peter Dimov Opened: 2007-05-10 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [refwrap.const].

View all issues with C++11 status.

Discussion:

A reference_wrapper can be constructed from an rvalue, either by using the constructor, or via cref (and ref in some corner cases). This leads to a dangling reference being stored into the reference_wrapper object. Now that we have a mechanism to detect an rvalue, we can fix them to disallow this source of undefined behavior.

Also please see the thread starting at c++std-lib-17398 for some good discussion on this subject.

[ 2009-05-09 Alisdair adds: ]

Now that ref/cref are constained that T must be an ObjectType, I do not believe there is any risk of binding ref to a temporary (which would rely on deducing T to be an rvalue reference type)

However, the problem for cref remains, so I recommend retaining that deleted overload.

[ 2009-05-10 Howard adds: ]

Without:

template <class T> void ref(const T&& t) = delete;

I believe this program will compile:

#include <functional>

struct A {};

const A source() {return A();}

int main()
{
   std::reference_wrapper<const A> r = std::ref(source());
}

I.e. in:

template <ObjectType T> reference_wrapper<T> ref(T& t);

this:

ref(source())

deduces T as const A, and so:

ref(const A& t)

will bind to a temporary (tested with a pre-concepts rvalue-ref enabled compiler).

Therefore I think we still need the ref-protection. I respectfully disagree with Alisdair's comment and am in favor of the proposed wording as it stands. Also, CWG 606 (noted below) has now been "favorably" resolved.

[ Batavia (2009-05): ]

We agree with the proposed resolution. Move to Tentatively Ready.

Proposed resolution:

In 22.10 [function.objects], add the following two signatures to the synopsis:

template <class T> void ref(const T&& t) = delete;
template <class T> void cref(const T&& t) = delete;

[ N2292 addresses the first part of the resolution but not the second. ]

[ Bellevue: Doug noticed problems with the current wording. ]

[ post Bellevue: Howard and Peter provided revised wording. ]

[ This resolution depends on a "favorable" resolution of CWG 606: that is, the "special deduction rule" is disabled with the const T&& pattern. ]