Могу ли я изменить тип удержания в std :: варианте из вызова std :: visit - программирование
Подтвердить что ты не робот

Могу ли я изменить тип удержания в std :: варианте из вызова std :: visit

Вызывает ли следующий код неопределенное поведение?

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, этот код переназначает A то же время сохраняя ссылку на ранее сохраненный объект типа B Однако, поскольку ссылка больше не используется после назначения, я чувствую, что код в порядке. Однако будет ли стандартная библиотека свободна для реализации std::visit таким образом, чтобы вышеприведенное поведение было неопределенным?

4b9b3361

Ответ 1

Код в порядке.

В спецификации std::visit нет требования, чтобы посетитель не менял альтернативу ни одному из вариантов, на которые он вызывается. Единственное требование:

Требуется: Для каждой действительной упаковки m, e(m) должно быть действительным выражением. Все такие выражения должны быть одного типа и категории значения; в противном случае, программа плохо сформирована.

Ваш посетитель является допустимым выражением для каждого m и всегда возвращает void, поэтому он удовлетворяет требованиям и имеет четко определенное поведение.