23 General utilities library [utilities]

23.7 Variants [variant]

23.7.3 Class template variant [variant.variant]

23.7.3.3 Assignment [variant.assign]

variant& operator=(const variant& rhs);

Пустьj будетrhs.index().

Effects:

  • Если ни один из значений*this неrhs имеет значения, эффекта нет. Иначе,

  • если*this содержит значение, ноrhs не содержит, уничтожает значение, содержащееся в,*this и устанавливает*this значение, не содержащее значения. Иначе,

  • ifindex() == jприсваивает значение, содержащееся в,rhs значению, содержащемуся в*this. Иначе,

  • если либо,is_­nothrow_­copy_­constructible_­v<Tj> либо !is_­nothrow_­move_­constructible_­v<Tj> равноtrue, эквивалентноemplace<j>(get<j>(rhs)). Иначе,

  • эквивалентноoperator=(variant(rhs)).

Returns:*this.

Postconditions:index() == rhs.index().

Remarks: Эта функция не должна участвовать в разрешении перегрузки, за исключением случаев, когда она is_­copy_­constructible_­v<Ti> && is_­copy_­assignable_­v<Ti> предназначенаtrue для всехi.

variant& operator=(variant&& rhs) noexcept(see below);

Пустьj будетrhs.index().

Effects:

  • Если ни один из значений*this неrhs имеет значения, эффекта нет. Иначе,

  • если*this содержит значение, ноrhs не содержит, уничтожает значение, содержащееся в,*this и устанавливает*this значение, не содержащее значения. Иначе,

  • ifindex() == jприсваиваетget<j>(std​::​move(rhs)) значение, содержащееся в*this. Иначе,

  • эквивалентноemplace<j>(get<j>(std​::​move(rhs))).

Returns:*this.

Remarks: Эта функция не должна участвовать в разрешении перегрузки, за исключением случаев, когда она is_­move_­constructible_­v<Ti> && is_­move_­assignable_­v<Ti> предназначена true для всехi. Выражение внутриnoexcept эквивалентно: is_­nothrow_­move_­constructible_­v<Ti> && is_­nothrow_­move_­assignable_­v<Ti> для всехi.

  • Если во время вызоваTjконструкции move вызывается исключение (приj условииrhs.index()), чтоvariant объект не будет иметь значения.

  • Если во время вызоваTjприсваивания перемещения возникает исключение , состояние содержащегося в нем значения определяется гарантией безопасности исключенийTjприсваивания перемещения;index() будетj.

template <class T> variant& operator=(T&& t) noexcept(see below);

ПозвольтеTj быть типом, который определяется следующим образом: построить мнимую функциюFUN(Ti) для каждого альтернативного типа Ti. Перегрузка,FUN(Tj) выбранная разрешением перегрузки для выражения,FUN(std​::​forward<T>(​t)) определяет альтернативу,Tj которая является типом содержащегося значения после присвоения.

Effects:

  • Если*this содержитTj, присваиваетstd​::​forward<T>(t) значение, содержащееся в*this. Иначе,

  • еслиis_­nothrow_­constructible_­v<Tj, T> || !is_­nothrow_­move_­constructible_­v<Tj> естьtrue, эквивалентноemplace<j>(std​::​forward<T>(t)). Иначе,

  • эквивалентноoperator=(variant(std​::​forward<T>(t))).

Postconditions: holds_­alternative<Tj>(*this) естьtrue, сTj выбранной мнимой функцией разрешения перегрузки, описанной выше.

Returns:*this.

Remarks: Эта функция не будет участвовать в разрешении перегрузки , если только is_­same_­v<decay_­t<T>, variant> не будетfalse, если только is_­assignable_­v<Tj&, T> && is_­constructible_­v<Tj, T> не будетtrue, и если выражениеFUN(std​::​forward<T>(t))FUN того вышеупомянутый набор функций мнимых) хорошо сформированы.

[Note:

variant<string, string> v;
v = "abc";

неправильно сформирован, поскольку оба альтернативных типа имеют одинаково жизнеспособный конструктор для аргумента. ]end note

Выражение внутриnoexcept эквивалентно:

is_nothrow_assignable_v<Tj&, T> && is_nothrow_constructible_v<Tj, T>
  • Если во время присваиванияstd​::​forward<T>(t) значению, содержащемуся в*this, возникает исключение , состояние содержащегося значения и t определяется гарантией безопасности исключений в выражении присваивания;valueless_­by_­exception() будетfalse.

  • Если во время инициализации содержащегося значения возникает исключение,variant объект может не содержать значения.