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
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 anyway.
(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.