Boost logo

Boost :

Subject: [boost] [variant] Please vote for behavior (Was: Basic rvalue and C++11 features seupport)
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2013-01-21 08:39:13


Current implementation of recursive_wrapper move constructor is not optimal:

recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
    : p_(new T(std::move(operand.get()) ))
{ }

During descussion were made following proposals:

I: Leave it as is
  - bad performance
  - can not provide noexcept guarantee

II: Set operand.p_ to NULL, add BOOST_ASSERT in get operations
  + good performance
  + provides noexcept guarantee for move constructor
  + optimization will be used even if varinat has no type with trivial
default constructor
  + easy to implement
  - triggers an assert when user tries to reuse moved object
  - adds an empty state to the recursive_wrapper

III: Make recursive_wrapper and variant cooperate, enable move for
varinat in the presence of recursive_wrappers only when there is at
least one type that is nothrow-default-constructible, regardless of
whether it's current. It is easyer to understand by example:
        typedef variant<int, recursive_wrapper<foo>> V;
        V v1( std::move(v2) );
        This move-constructs v1 from v2 and leaves int() into v2.
  + good performance
  + provides noexcept guarantee for rcursive_wrapper
  + does not adds an empty state
  - optimization won't trigger if varinat has no type with trivial
default constructor
  - hard to implement
  - user may be obscured by the fact, that v2 from the example now contains int

IV: After move away, delay construction of type held by
recursive_wrapper till it will be be required.
  +/- good performance? but more checks
  + provides noexcept guarantee for rcursive_wrapper
  + does not adds an explicit empty state
  + optimization will be used even if varinat has no type with trivial
default constructor
  +/- not hard to implement
  --- additional requirement for type T of recursive_wrapper: it must
be default constructible
  - less obvious behavior for user (for example get() function would
construct values, allocate memory and can possibly throw)

Please, vote for solution or propose a better one.

P.S.:
As I know Joel de Guzman votes for solution II (and totally agains
solution I, because it is too slow).
I wanted to leave as is (solution I) or use solution IV, but Joel
talked me to solution II.

P.P.S.:
More info can be obtained from ticket #7718
https://svn.boost.org/trac/boost/ticket/7718
 and previous series of letters.

--
Best regards,
Antony Polukhin

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