On Mon, Apr 29, 2019 at 1:44 PM Steven Watanabe via Boost
AMDG
On 4/29/19 11:30 AM, Antony Polukhin via Boost wrote:
I've merged a very cool optimization by Nikita Kniazev into the master branch. From now on boost::variant does pointer stealing for recursive variants.
This significantly improves the performance of the variants move constructors.
However if you use a variant variable after the std::move for anything except destruction and assignment then you're getting an UB. Beware!
boost::variant goes to great lengths to prevent exactly this situation. You just broke it. This change is unacceptable. Please revert it. This optimization can be used iff. you have a way to construct a valid object in the rhs.
Stressing that, as Steven points out, this wouldn't violate the never-empty guarantee *if* after stealing you were able to default-construct something on the right-hand side and update the discriminator accordingly -- similar to what is done in other parts of variant. I think that if people want an alternative to this that is closer to what the change does, we'd probably want a template different from recursive_wrapper that explicitly has an empty state, leaving recursive_wrapper and variant's invariants intact. In other words, an additional template that is just an `optional` equivalent that always uses dynamic storage (at least for types that can be incomplete). This would be a different type from recursive_wrapper so as to not weaken the invariants of recursive_wrapper, but it could still be a type that variant knows about in much the same way, if that were to prove desirable. Such an optional-equivalent would be more generally useful anyway. -- -Matt Calabrese