我可以在对std :: visit的调用中更改std :: variant中的保留类型

bur*_*nck 22 c++ c++17 std-variant

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

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);
Run Code Online (Sandbox Code Playgroud)

特别是,当变体不包含时A,此代码将重新分配,A同时仍保留对先前持有的type对象的引用B。但是,由于分配后不再使用该引用,因此我觉得代码很好。但是,标准库是否可以以std::visit 上述方式不确定的方式自由实施?

Bar*_*rry 18

代码很好。

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

要求:对于每个有效的pack me(m)应为一个有效的表达式。所有这些表达式应具有相同的类型和值类别;否则,程序格式不正确。

您的访客是每个人的有效表达式,m并且始终会返回void,因此它满足要求并具有明确定义的行为。