|
Boost : |
Subject: Re: [boost] [Boost.Move] A few notes
From: Dan Ivy (danivy.mail_at_[hidden])
Date: 2012-01-13 10:13:15
On Fri, Jan 13, 2012 at 1:04 AM, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
> Here's my position:
> - Ideally, client code written for both C++11 and C++03 should not have
> "ugly" workarounds for C++03 deficiencies, and that's basically what
> wrapping all function parameters in some BOOST_MOVE macro (or similar)
> would be, a workaround.
No argument here.
> - If you really want to guarantee C++11-level performance in C++03 and the
> interface can't otherwise guarantee this, and this necessitates some kind
> of workaround, then one workaround (wrapping in a BOOST_MOVE macro) is just
> about as bad as another (storing a temporary and explicitly moving).
Allow me to disagree. I think one altenative is way better than the
other, as it doesn't force you to spread your call expression over
multiple statements, which is, aside from being obscure (BOOST_MOVE is
ugly, but pretty straight-forward), is not applicable in some contexts
(i,e, initializer lists).
>
> In any case, even if we did end up agreeing that wrapping function
> parameters in a BOOST_MOVE macro was desireable, this doesn't entirely
> preclude BOOST_FWD_REF( T ) from expanding to T const &;
That's right, these are two separate things.
moveable
> temporaries would still be moved. The loss is that const-ness of lvalues is
> not preserved, but that isn't a common case.
Not too common, but far from being a corner case either.
> [...]
>> Interesting. Could you provide a reference or an example?
>
> Here's the idea. In C++11, you can just get away with
> [...]
>
Thanks for expanding. That's a clever trick :). I thought you were
taking about something a bit different though, as this method doesn't
scale to functions taking more than a single parameter (it's
theoretically possible, but not practical), so it's not a general
solution to forwarding.
Btw, if that's all you're trying to do, won't something like this be a
lot simpler?
#include <iostream>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
template <typename T>
struct movable {};
struct i_can_move : movable<i_can_move> {};
template <typename T>
void what_is(T&) {
if(!boost::is_const<T>::value)
std::cout << "modifiable lvalue" << std::endl;
else
std::cout << "const lvalue" << std::endl;
}
template <typename T>
typename boost::disable_if<
boost::is_convertible<T, movable<T> >
>::type what_is(const T&) {
std::cout << "non-movable const-lvalue "
"or rvalue" << std::endl;
}
template <typename T>
void what_is(const movable<T>&) {
std::cout << "rvalue" << std::endl;
// No indirect call, and we get to know what T is
}
int main()
{
{
i_can_move x;
const i_can_move y = x;
what_is(x);
what_is(y);
what_is(i_can_move());
}
std::cout << std::endl;
{
int x;
const int y = 123;
what_is(x);
what_is(y);
what_is(123);
}
}
> [...]
>> So, it seems that you're already using the same thing I suggest...
>>
>
> Well, any function using BOOST_FWD2_REF in its parameter list is only
> passed parameters that are lvalues or the result of a boost::forward. So, I
> guess I'm using the same thing, but it doesn't sound like it's in the same
> context...?
But since we only have one BOOST_FWD_REF, I belive it should be
applicable to any context (and you belive that it should be
"optimized" for the most common one, point is clear, let's not open
that again ;) )
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk