Boost logo

Boost :

Subject: Re: [boost] [Review] Formal Review: Boost.Move - add'l suggestions / questions
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2010-05-14 07:32:48


On 12/05/2010 22:08, Jeffrey Lee Hellrung, Jr. wrote:

> I don't think, as implemented, is_movable works for non-class types (at
> least that used to be the case, and I think the only change in the
> implementation has been the introduction of a boost::mpl::bool_). I
> think for non-class types T, at least in c++03, is_movable<T> should
> evaluate to false without causing a compiler error.

Well, it shouldn't cause any error, is_convertible should lead to false:

    //This works in MSVC 7.1
    bool mv = ::boost::is_movable<int>::value;

> I don't recall seeing anything concerning has_nothrow_move other than a
> short description about how it defaults to false and could hurt
> performance if not specialized. Can you explain the intended use for
> has_nothrow_move? Is this related to N2983 [1]? Speaking of which, do
> you have any idea what the status of throwing move constructors is as
> far as the c++ committee is concerned, whether you agree with the
> resolution provided by N2983, and if so, have you thought about
> providing move_if_noexcept (or something similar)?

Since this has been a moving target until now, I haven't seriously
thought about emulating those proposals, but I do expect to work on them
in the future, when they are completely definitive. Regarding
performance gains with has_nothrow_move, you can optimize away some
exception rollback actions in container internals if you know that
moving objets will not throw. And to use some advanced memory allocation
strategies, like forward buffer expansion, you need this nothrow
guarantees because some containers, like vector, require strong
exception guarantees for some operations (like push_back).

> If has_nothrow_move turns out to be widely used, it may be a good idea
> to package the "no-throw-ness" of the move constructor within a move
> emulation enabling macro (ENABLE_NOTHROW_MOVABLE), e.g., by defining a
> typedef that has_nothrow_move can detect, or maybe a boolean static
> constant within the class indicating whether the move constructor
> throws, so that you can make the "no-throw" property conditional on the
> "no-throw-ness" of member objects. In any case, one step at a time...

The good part of template specializations is that you don't need to
instantiate the class to check if the class has that property, and this
is important specially when defining recursive data types like recursive
containers:

class recursive
{
   vector<recursive> leafs;
};

> As far as the utility of is_movable in c++0x, it looks like it's only
> used in uninitialized_move and uninitialized_copy_or_move. This doesn't
> seem like enough justification to provide it for c++0x, since
> uninitialized_{copy_or_}move *could* be implemented without it just
> fine. Furthermore, is_movable will only be true in c++0x if a movable
> type has a nested typedef boost_move_emulation_t, which seems to
> exclude, e.g., STL data structures. I would think a simpler course of
> action would be to relegate is_movable to strictly c++03...

Yes, that might be an option. I do use it in containers for some sfinae
tricks, but I think it's only for C++03 code. It seems that in C++0x
it's not easy to know if a class really has a rvalue reference overload
constructor (or at least, it wasn't some time ago, maybe things have
changed in recent proposals-drafts), so it might be possible to limit it
to C++03.

> I've looked through the documentation and have typo suggestions, but
> I'll have to get to those later...

Ok, thanks again,

Ion


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