Могу ли я изменить тип удержания в 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
таким образом, чтобы вышеприведенное поведение было неопределенным?
Ответы
Ответ 1
Код в порядке.
В спецификации std::visit
нет требования, чтобы посетитель не менял альтернативу ни одному из вариантов, на которые он вызывается. Единственное требование:
Требуется: Для каждой действительной упаковки m
, e(m)
должно быть действительным выражением. Все такие выражения должны быть одного типа и категории значения; в противном случае, программа плохо сформирована.
Ваш посетитель является допустимым выражением для каждого m
и всегда возвращает void
, поэтому он удовлетворяет требованиям и имеет четко определенное поведение.