May I change the held type in a std::variant from within a call to std::visit

我怕爱的太早我们不能终老 提交于 2019-11-29 16:24:56

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/55187548/may-i-change-the-held-type-in-a-stdvariant-from-within-a-call-to-stdvisit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!