Does the following code invoke undefined behaviour?
std::variant<A,B> v = ...; std::visit([&v](auto& e){ if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>) e.some_modifying_operation_on_A(); else { int i = e.some_accessor_of_B(); v = some_function_returning_A(i); } }, v);
In particular, when the variant does not contain an A
, this code re-assigns an A
while still holding a reference to the previously held object of type B
. However, because the reference is not used anymore after the assignment, I feel the code is fine. However, would a standard-library be free to implement std::visit
in a way such that the above is undefined behaviour?
The code is fine.
There is no requirement in the specification of std::visit
that the visitor not change the alternative of any of the variants it is invoked on. The only requirement is:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
Your visitor is a valid expression for each m
and always returns void
, so it satisfies the requirements and has well-defined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With