|
Boost : |
Subject: Re: [boost] [Review] Formal Review: Boost.Move - add'l suggestions / questions
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-05-15 01:56:17
On 5/14/2010 4:32 AM, Ion Gaztañaga wrote:
> 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;
Hmmm...yes, you're right. I seem to remember that, at some point, it
looked like is_movable was trying to instantiate rv< int > (and hence
complained about deriving from int), but I don't have the context
anymore... :/
>> 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).
Right, I understand the optimization considerations. I'm torn whether
has_nothrow_move is appropriate to include at this juncture. About all
I can say is that it *currently* lacks sufficient explanation in the
documentation as to its purpose. As you said, throwing move
constructors has been a "moving target". I'm hoping someone with more
familiarity on the subject can step in and advise.
>> 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;
> };
Yes, I agree, it is certainly convenient to be able to use
has_nothrow_move<T> even if T is incomplete. I still don't like the
idea of forcing users to specialize has_nothrow_move when it seems like
the *common* case is non-throwing move constructors...hmmmm...
>> 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 think that would be prudent.
- Jeff
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk