24

以下代码是否调用未定义的行为?

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);

特别是,当变体不包含 时A,此代码重新分配一个Awhile 仍然持有对先前持有的类型对象的引用B。但是,由于赋值后不再使用引用,所以我觉得代码很好。但是,标准库是否可以自由地以std::visit 上述未定义行为的方式实现?

4

1 回答 1

18

代码很好。

规范中没有要求std::visit访问者不更改调用它的任何变体的替代方案。唯一的要求是:

Requires:对于每个有效的 pack me(m)应该是一个有效的表达式。所有此类表达式应具有相同的类型和值类别;否则,程序格式错误。

您的访问者是 each 的有效表达式,m并且总是返回void,因此它满足要求并具有明确定义的行为。

于 2019-03-15T17:28:15.983 回答