|
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