Boost logo

Boost :

Subject: Re: [boost] [move] new rvalue reference emulation
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-04-11 16:01:01


On Mon, Apr 11, 2011 at 5:46 AM, Eric Niebler <eric_at_[hidden]> wrote:

> > On 4/10/2011 9:22 PM, Jeffrey Lee Hellrung, Jr. wrote:
> >>
> >> I have a follow-up to my original message regarding a typeless
> >> emulated rvalue reference. I was disappointed in the lack of
> >> feedback (other than Dave) on the original message, which might
> >> mean that those who took the time to parse the message didn't think
> >> it was worth pursuing;
>
> Not at all. I am very interested in improved move emulation in C++03.
> Speaking solely from myself, I just don't have the time to do the
> technical investigation that it would take to respond intelligently to
> your mail. I expect some others are in the same position. Please don't
> be discouraged!
>

Totally understandable. Perhaps a short summary will be useful, with full
details provided in [1].

I'm assuming familiarity with C++0x rvalue references. For those
unfamiliar, I recommend the "RValue References: Moving Forward" sequence of
articles by Dave Abrahams, e.g., [2]. I also recommend familiarity with
Boost.Move [3,4], which basically provides the current state-of-the-art move
and rvalue reference emulation within C++03.

I propose to supplement Boost.Move to very closely approximate perfect
forwarding. To be a little bit more specific...

One of the problems that rvalue references solves is the forwarding problem
[5]. To the best of my knowledge (until now!), the best approximation to
generic forwarding in C++03 turns rvalues into lvalues ([5], indeed, says as
much), but preserving the rvalueness of a function argument is important to
identify when one can safely move from the argument. I have devised a
technique (let's call it the "typeless emulated rvalue reference (TERR)
technique") that, when combined with the existing Boost.Move emulation
framework, can actually preserve rvalueness for *arbitrary*
(move-emulation-enabled) types. To get an idea of what such a forwarding
overload set might look like, let's modify the first example,
unary_function_wrapper, from [5] to use a TERR to achieve perfect
forwarding:

template< class F >
struct unary_function_wrapper
{
    unary_function_wrapper(F f) : m_f(f) { }

    template< class T >
    void operator()(T& x) { m_f(x); }

    // genrv< Visitor > is a TERR
    typedef genrv< unary_function_wrapper > genrv_type;

    template< class T >
    typename boost::disable_if< boost::is_convertible< T&, genrv_type >
>::type
    operator()(T const & x) { m_f(x); }

    void operator()(genrv_type x) { x(*this); }

private:
    F m_f;
};

Now, if X is *any* move-emulation-enabled class, unary_function_wrapper<F>
will capture X-rvalues by emulated-rvalue-reference rv<X>& and forward this
onto the wrapper function object m_f, thus preserving rvalueness. Of
course, it's far from obvious how that happens, exactly, just given the
above code, so for those interested in *how* that's achieved, I again refer
you to [1].

Hopefully this summary helps determine whether one should investigate [1] in
detail or not.

- Jeff

[1] http://thread.gmane.org/gmane.comp.lib.boost.devel/217478/focus=217772
[2] http://cpp-next.com/archive/2009/09/move-it-with-rvalue-references/
[3] http://igaztanaga.drivehq.com/libs/move/doc/html/index.html
[4] http://svn.boost.org/svn/boost/sandbox/move/
[5] http://cpp-next.com/archive/2009/12/onward-forward/


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk