Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++17 status.

2904. Makevariant move-assignment more exception safe

Section: 22.6.3.4[variant.assign]Status:C++17Submitter: United StatesOpened: 2017-02-03Last modified: 2020-09-06

Priority:Not Prioritized

View otheractive issues in [variant.assign].

View all otherissues in [variant.assign].

View all issues withC++17 status.

Discussion:

Addresses US 119 and CH 7

The copy-assignment operator is very careful to not destroy the contained element until after a temporary has been constructed, which can be safely moved from.

This makes thevalueless_by_exception state extremely rare, by design.

However, the same care and attention is not paid to the move-assignment operator, nor the assignment-from-deduced-value assignment template. This concern should be similarly important in these cases, especially the latter.

Proposed change: —

[2017-03-02, Kona, Casey comments and suggests wording]

The wording below has been developed withmuch input from Tomasz.

[Kona 2017-03-02]

Accepted as Immediate to resolve NB comment.

Proposed resolution:

This wording is relative toN4640.

  1. Modify 22.6.3.4[variant.assign] as indicated:

    [Drafting note: Presentation of para 9 immediately below has been split into individual bullets.]

    variant& operator=(const variant& rhs);

    Letj berhs.index().

    -1-Effects:

    1. (1.1) — If neither*this norrhs holds a value, there is no effect. Otherwise,

    2. (1.2) — if*this holds a value butrhs does not, destroys the value contained in*this and sets*this to not hold a value. Otherwise,

    3. (1.3) — ifindex() ==jrhs.index(), assigns the value contained inrhs to the value contained in*this. Otherwise,

    4. (1.?) — ifis_nothrow_copy_constructible_v<Tj> || !is_nothrow_move_constructible_v<Tj> istrue, equivalent toemplace<j>(get<j>(rhs)). Otherwise,

    5. (1.4) —equivalent tooperator=(variant(rhs))copies the value contained inrhs to a temporary, then destroys any value contained in*this. Sets*this to hold the same alternative index asrhs and initializes the value contained in*this as if direct-non-list-initializing an object of typeTj withstd::forward<Tj>(TMP), withTMP being the temporary andj beingrhs.index().

    -2-Returns:*this.

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

    -4-Remarks: This function shall not participate in overload resolution unlessis_copy_constructible_v<Ti>&& is_move_constructible_v<Ti> && is_copy_assignable_v<Ti> istrue for alli.

    1. (4.1) — If an exception is thrown during the call […]

    2. (4.2) — If an exception is thrown during the call […]

    3. (4.3) — If an exception is thrown during the call […]

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

    Letj berhs.index().

    -5-Effects:

    1. (5.1) — If neither*this norrhs holds a value, there is no effect. Otherwise,

    2. (5.2) — if*this holds a value butrhs does not, destroys the value contained in*this and sets*this to not hold a value. Otherwise,

    3. (5.3) — ifindex() ==jrhs.index(), assignsget<j>(std::move(rhs)) to the value contained in*this, withj beingindex(). Otherwise,

    4. (5.4) —equivalent toemplace<j>(get<j>(std::move(rhs)))destroys any value contained in*this. Sets*this to hold the same alternative index asrhs and initializes the value contained in*this as if direct-non-list-initializing an object of typeTj withget<j>(std::move(rhs)) withj beingrhs.index().

    […]

    […]

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

    -8- […]

    -9-Effects:

    1. (9.1) — If *this holds aTj, assignsstd::forward<T>(t) to the value contained in*this. Otherwise,

    2. (9.?) — ifis_nothrow_constructible_v<Tj, T> || !is_nothrow_move_constructible_v<Tj> istrue, equivalent toemplace<j>(std::forward<T>(t)). Otherwise,

    3. (9.3) —equivalent tooperator=(variant(std::forward<T>(t)))destroys any value contained in*this, sets*this to hold the alternative typeTj as selected by the imaginary function overload resolution described above, and direct-initializes the contained value as if direct-non-list-initializing it withstd::forward<T>(t).


[8]ページ先頭

©2009-2026 Movatter.jp