Boost logo

Boost :

Subject: Re: [boost] [move] pre-review comments
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-04-03 14:03:58


Jeffrey Lee Hellrung, Jr. wrote:
> I have some (long overdue) comments concerning Ion Gaztanaga's proposed
> Boost.Move library.

One more thing: A section can be added on overloading to capture
rvalues, as long as you know the type (or types) of rvalues you want to
capture (this is only difficult in C++03, hence only applies on C++03).

The first method to do this is to overload on parameter types T&, const
boost::rv<T>&, and boost::rv<T>&. The former two bind to lvalues
references to T, and the latter one will bind to rvalues of T:

template< class T >
struct my_vector
{
     void push_back(T& x) { /* copy x */ }
     void push_back(const rv<T>& x) { /* copy x */ }
     void push_back(rv<T>& x) { /* move x */ }
};

Clearly, the definitions of push_back(T&) and push_back(const rv<T>&)
could be shared (the former can forward to the latter, or they can each
call a common implementation function).

To make this easy to implement uniformly for both C++03 and C++0x
compilers, I've defined metafunctions (actually, I've just extended
call_traits) to give me the types lvalue_param_type,
const_lvalue_param_type, and rvalue_param_type. These definitions
differ depending on if T is movable or not, and on whether the compiler
supports rvalue references or not.

The downside of the above is the difference in behavior between C++03
compilers and C++0x compilers. Specifically, overloads like

void push_back(const T& x) { /* copy x */ }
void push_back(T&& x) { /* move x */ }

for C++0x are able to induce implicit conversions to T, whereas the 3
C++03 overloads will not be able to induce such conversions.

To alleviate this shortcoming, the second method to provide overloads to
capture rvalues is use a templated overload that SFINAE-outs any binding
to the (known) rvalue type (or types):

template< class T >
struct my_vector
{
     template< class U > void push_back(U& x) { /* copy x */ }
     void push_back(rv<T>& x) { /* move x */ }
     template< class U >
     typename disable_if< is_same<U,T> >::type
     push_back(const U& x) { /* copy x */ }
};

This is more complicated, but gets closer to the behavior on C++0x
compilers.

Ion (and others), let me know what you think. Hopefully these last 2
emails generate some discussion. Also, Ion, if there's anything I can
do to help out with the development, let me know.

- Jeff


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