Boost logo

Boost :

Subject: Re: [boost] [variant] Please vote for behavior (Was: Basic rvalue and C++11 features seupport)
From: Sergey Cheban (s.cheban_at_[hidden])
Date: 2013-01-21 14:27:36


On 21.01.2013 17:39, Antony Polukhin wrote:

> I: Leave it as is
> - bad performance
> - can not provide noexcept guarantee
>
I vote against this solution because of it's disadvantages.

> 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
Let's think about non-recursive variants. For example:

// both CFileObj and CDatabaseObj are movable, not copyable and
// not nothrow-default-constructible
boost::variant< CFileObj, CDatabaseObj > v1( CFileObj(SomeFileName) );
boost::variant< CFileObj, CDatabaseObj > v2( std::move( v1 ) );

// What would be the state of v1 at this point?

It seems to me that the second solution solves only a part of the
problem. So, I don't vote for it.

>
> 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
I think this is a best solution. We have to leave the moved-from object
in some valid state and cannot specify this state in the code. So, we
need the default constructor (or, may be, something else).

> 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)
I think that get() MUST NOT throw. So, I vote against this solution.

-- 
Sergey Cheban

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