Boost logo

Boost Users :

Subject: Re: [Boost-users] variant has non-trivial destructor even when all constituents have trivial destructor
From: Agustín K-ballo Bergé (kaballo86_at_[hidden])
Date: 2015-11-28 12:09:11


On 11/28/2015 1:27 AM, ☂Josh Chia (谢任中) wrote:
> I used integers only to keep the example simple.
>
> In reality I have a few structs with trivial copy-assignment operator
> and trivial destructor that I make members of the variant. variant lets
> me use static visitors.

The complexity of the union members don't make the discriminated-union
implementation more complex. The number of elements in the union,
however, would.

> If I use my own union with switch statements instead of variant with
> static visitors, when I add a new type to the union, I may forget to
> update some switch statement but with static visitors I'll get a
> compiler error if I forget to update any static visitor.
>
> The code may be simpler in some sense if I use a union but it's safer
> and more maintainable if I use a variant, especially if I would have to
> maintain many switch statements.

Nothing stops you from providing your own switch-driven static
visitation. Again, the number of times you'd need to implement this
might matter.

> I could implement my own static visitor mechanism just for this
> union-ish type but that seems like reinventing the wheel.

Nod. It's a slightly different shaped wheel. In particular, since the
elements will be trivial, you need not -and in fact want not to-
implement any special member function. The only thing you'll be needing
from `boost::variant` is the discriminator and checked access,
everything else it does is just boilerplate overhead (that in your
particular use case isn't even needed at all). It could likely still
beat having to reinvent a generic wheel by a large factor.

> So, it would be convenient if I could use
> boost::lock_free::queue<variant<...>> on my structs, although I have
> barely any idea on the implementation complexity required.

It's considerably complex to do it generically given the current
language rules. A trivial special member function, if user-declared,
must be defaulted in the first definition. Transparent triviality forces
splitting the implementation in several different classes that duplicate
functionality (not all of it can be abstracted away, e.g. constructors),
just to be able to choose between `= default` or `{ ... }` for the one
special member function. You can read more about it here:
https://akrzemi1.wordpress.com/2012/12/13/constexpr-unions/

Note that the proposed `std::experimental::variant`, as currently
specified, won't support your use case either (`variant<int, float>`
will be trivially-destructible because `constexpr`, but not
trivially-copyable).

Concepts will make this trivial:
http://melpon.org/wandbox/permlink/mtE1Y1kQcXa3nRXO

Until then, you could try working on a patch to make `boost::variant` of
trivially-copyable elements trivially-copyable itself. However, if you
are looking for a quick turnaround, I suspect going with a plain
discriminated-union would get you there considerably faster. That's
assuming there's only one or two of these guys that need to be used in a
lockfree scenario.

Regards,

-- 
Agustín K-ballo Bergé.-
http://talesofcpp.fusionfenix.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net