Boost logo

Boost :

Subject: Re: [boost] [variant2] documentation request
From: Peter Dimov (pdimov_at_[hidden])
Date: 2019-03-05 14:54:20


Niall Douglas wrote:
> > double_buffered_variant, really means "give me strong exception safety.
> > I don't care about the cost."
>
> Not quite. It means "I don't trust that somebody won't mess up this
> variant during code maintenance in the next decade".

Your reformulation aside, "give me the strong guarantee" is exactly what it
means, and double buffering is only means to that end and insufficient in
itself.

A strong guarantee variant must never delegate to the assignment operator of
the contained type; it has to destroy and recreate even when the types
match.

I have argued for this behavior (for std::variant and std::optional) in the
past. Aside from delivering the strong guarantee, it can also be used to
make a non-assignable type assignable by wrapping it in a variant<> or
optional<>. But there's too much opposition and it's never going to be
accepted for std::variant or std::optional.

The strong guarantee is somewhat of an annoyance. It's almost never needed,
and it doesn't compose. If you have two types T and U, which offer the basic
guarantee on assignment, so does struct { T t; U u; }. And if they offer the
noexcept guarantee on assignment, so does the struct. But if they offer the
strong guarantee on assignment, the struct doesn't, and there's no way to
make it so (using only the provided strong assignment; if you have noexcept
swap, you can, but that's because it's noexcept, a strong swap would
similarly be useless).

So the strong guarantee is almost always the wrong thing to provide. You
want basic for the copy assignment, and noexcept for the move assignment.
And people who argue against strong for variant<> have a point.


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