Subject: Re: [boost] variant2 never empty guarantees
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-06-08 23:05:47
On 9/06/2017 01:22, Andrzej Krzemienski wrote:
> 2017-06-08 15:01 GMT+02:00 Peter Dimov:
>>> I'm not sure I understand this fully; could you please explain from what
>>> expressions, and under what conditions, you expect the strong guarantee?
>>> variant<X, Y> v1, v2;
>>> X x;
>>> v1= v2; // do you expect strong guarantee here?
>>> v1 = std::move(v2); // here?
>>> v1 = x; // here?
>>> v1 = std::move(x); // here?
>>> v1.emplace<X>(); // here?
>> Anyone? This is a genuine inquiry. How can I give you strong guarantee if
>> you don't tell me when and where you want it?
> Maybe nobody needs the strong guarantee? This is definitely the case for my
> programs. I put variants in different containers. But if exception is
> thrown while modifying them I am destroying the entire data structure. I do
> not need the previous state. If I cannot put the new one, I cannot proceed
> (I am not saying such guarantee is useless. I just observe that the need
> occurred in my programs.)
The only case that I can think of at the moment is for something like a
state machine, where each type in the variant is a possible state and
the current value is the current state. If a transition fails via
throwing from the new state constructor then presumably the state
machine should remain in the previous state.
Having said that, the proposed implementations of strong guarantee
wouldn't work for that case anyway, since that sort of state machine
also generally assumes that the current state destructor is run strictly
before the new state constructor, and that wouldn't be the case if you
stacked a backup in case of exception. (Mind you, it also wouldn't be
the case even for basic assignment; they'd have to explicitly assign a
none_t or something first to make that happen.) So the right place to
handle that guarantee is in the state machine transition machinery, not
in variant itself.
People generally require that for x = f() then if f() throws x should be
unmodified (which is automatic based on how the language works); if it's
the assignment itself that throws then things are usually beyond
recovery anyway, since assignment is not really expected to throw for
any reason other than out of memory.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk