Niall Douglas wrote:
I just do not understand the antipathy here to a
double-buffered-by-default design, and thus the strong guarantee can be
easily made, rather than a worse-than-useless basic guarantee which is
only technically valid, but is certainly surprising.
First off, the basic guarantee isn't worse than useless, it's the minimum
standard that every non-broken component must meet, and everyone who argues
otherwise isn't worth listening to.
With that out of the way, though, variant2 may end up with the strong
guarantee anyway, for other reasons. Consider this example:
variant v;
v.emplace<1>( 1 );
v = get<1>( v )[ 0 ];
(a variation of which Antony Polukhin reported some time ago as a potential
defect in std::variant, if I'm not mistaken.)
What happens here is that on the last line, `v` on the left owns the `X`
value on the right. So when the implementation first destroys the old
contents of `v` to make room for the new `X`, the right hand side is
destroyed, and then undefined behavior occurs when we try to copy it into
`v`.
This is fixable. But when we fix it, we've paid much of the price required
for the strong guarantee, so we might as well offer that.
With respect to this example, there're the usual two schools of thought, one
saying it's the user's fault, don't penalize my variant for that, the other
preferring variant handle it. I'm trending towards the latter camp.