niedz., 14 kwi 2019 o 19:19 Rainer Deyke via Boost
On 13.04.19 19:26, Bjorn Reese via Boost wrote:
* std::variant which enters an invalid (valuless_by_exception) state. While that may be appropriate for some use cases, there are others where it is not. For instance, the variant may be used for a state machine where the alternative types are function object types to be invoked when events arrive. Having a valueless state is the wrong choice for this use case.
Wait. I don't understand how never-empty is an advantage in this example.
If the alternative types are function pointer types, then never-empty provides no improvement over valueless-by-exception. On an exception, the variant will simply contain a typed nullptr instead of being empty.
If the alternative types are non-empty function objects, then never-empty provides at best a marginal improvement over valueless-by-exception. On an exception, the variant will contain a wrong (default-constructed) function object.
If the alternative types are empty function objects, then the benefit of never-empty is still marginal. The variant will still contain a wrong function object, albeit one drawn from the pool of correct function objects. The invariants of the state machine can still be broken. Also, if the alternative types are empty function objects, then there is no reason for why their constructors should ever throw, so the never-empty guarantee should never come into play in the first place.
What am I missing here?
A global state machine is a very good illustration of the problem. std::variant cannot address this use case and everyone can see it immediately. We need a type with strong exception safety guarantee. variant2 (or Boost.Variant) cannot handle this use case either. But because of the misunderstanding of what the "select random value" guarantee offers, some programmers may be deceived and believe that this would work. This is why I like std::variant better: it does not try to confuse you about what you can and cannot do. Regards, &rzej;