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.

2016.Allocators must be no-throwswappable

Section: 16.4.4.6[allocator.requirements]Status:C++17Submitter: Daniel KrüglerOpened: 2010-11-17Last modified: 2017-07-30

Priority:2

View otheractive issues in [allocator.requirements].

View all otherissues in [allocator.requirements].

View all issues withC++17 status.

Discussion:

During the Batavia meeting it turned out that there is a definitionhole for types satisfying theAllocators requirements: The problembecame obvious when it was discussed whether allswap functions ofContainers with internal data handles can be safely taggedwithnoexcept or not. While it is correct that the implicitswap function of an allocator is required to be a no-throwoperation (because move/copy-constructors and assignment operators arerequired to be no-throw functions), there are no such requirementsfor specializedswap overloads for a particular allocator.

But this requirement is essential because theContainers arerequired to supportswappableAllocators, when the valueallocator_traits<>::propagate_on_container_swap evaluatestotrue.

[2011-02-10 Alberto, Daniel, and Pablo collaborated on the proposed wording]

The proposed resolution (based on N3225) attempts to solve the following problems:

  1. Table 44 — Allocator requirements, expression rowsX::propagate_on_container_copy_assignment,X::propagate_on_container_move_assignment, andX::propagate_on_container_swap only describe operations, but no requirements. In fact, if and onlyif these compile-time predicates evaluate totrue, theadditional requirementsCopyAssignable, no-throwMoveAssignable, and no-throw lvalueSwappable, respectively, are imposed on the allocator types.
  2. 23.2.2[container.requirements.general] p. 9 misses to refer to the correct swap conditions: The current wording does not relate to16.4.4.3[swappable.requirements] as it should and omits to mention that lvalues shall be swapped. Additional there is onesituation described twice in p. 8 and p. 9 (undefined behaviour unlessa.get_allocator() == b.get_allocator()orallocator_traits<allocator_type>::propagate_on_container_swap::value == true), which should be cleaned up.

[2011-04-08 Pablo comments]

I'm implementing a version of list now and I actually do find it impossible to write an exception-safe assignment operator unless I can assume that allocator assignment does not throw. (The problem is that I use a sentinel node and I need to allocate a new sentinel using the new allocator without destroying the old one -- then swap the allocator and sentinel pointer in atomically, without risk of an exception leaving one inconsistent with the other.

Please update the proposed resolution to add the nothrow requirement to copy-assignment.

[2014-02-14 Issaquah: Move to Ready]

Fix a couple of grammar issues related to callingswap and move to Ready.

Proposed resolution:

  1. Adapt the following three rows from Table 44 — Allocator requirements:

    Table 44 — Allocator requirements
    ExpressionReturn typeAssertion/note
    pre-/post-condition
    Default
    X::propagate_on_container_copy_assignmentIdentical to or derived fromtrue_type
    orfalse_type
    true_type only if an allocator of typeX should be copied
    when the client container is copy-assigned.See Note B, below.
    false_type
    X::propagate_on_container_move_assignmentIdentical to or derived fromtrue_type
    orfalse_type
    true_type only if an allocator of typeX should be moved
    when the client container is move-assigned.See Note B, below.
    false_type
    X::propagate_on_container_swapIdentical to or derived fromtrue_type
    orfalse_type
    true_type only if an allocator of typeX should be swapped
    when the client container is swapped.See Note B, below.
    false_type
  2. Following 16.4.4.6[allocator.requirements] p. 3 insert a new normative paragraph:

    Note B: IfX::propagate_on_container_copy_assignment::value is true,X shall satisfy theCopyAssignable requirements (Table 39 [copyassignable]) and the copy operation shall not throw exceptions. IfX::propagate_on_container_move_assignment::value is true,X shall satisfy theMoveAssignable requirements (Table 38 [moveassignable]) and the move operation shall not throw exceptions. IfX::propagate_on_container_swap::value is true, lvalues ofX shall be swappable (16.4.4.3[swappable.requirements]) and theswap operation shall not throw exceptions.

  3. Modify 23.2.2[container.requirements.general] p. 8 and p. 9 as indicated:

    8 - [..] The allocator may be replaced only via assignment orswap(). Allocator replacement is performed by copy assignment, move assignment, or swapping of the allocator only ifallocator_traits<allocator_type>::propagate_on_container_copy_assignment::value,allocator_traits<allocator_type>::propagate_on_container_move_assignment::value, orallocator_traits<allocator_type>::propagate_on_container_swap::value is true within the implementation of the corresponding container operation.The behavior of a call to a container'sswap function is undefined unless the objects being swapped have allocators that compare equal orallocator_traits<allocator_type>::propagate_on_container_swap::value is true. In all container types defined in this Clause, the memberget_allocator() returns a copy of the allocator used to construct the container or, if that allocator has been replaced, a copy of the most recent replacement.

    9 - The expressiona.swap(b), for containersa andb of a standard container type other thanarray, shall exchange the values ofa andb without invoking any move, copy, or swap operations on the individual container elements.Lvalues of aAnyCompare,Pred, orHashobjectstypes belonging toa andb shall be swappable and shall be exchanged byunqualified calls to non-membercallingswapas described in 16.4.4.3[swappable.requirements]. Ifallocator_traits<allocator_type>::propagate_on_container_swap::value istrue, thenlvalues ofallocator_type shall be swappable and the allocators ofa andb shall also be exchangedusing an unqualified call to non-memberby callingswapas described in 16.4.4.3[swappable.requirements]. Otherwise,theythe allocators shall not be swapped, and the behavior is undefined unlessa.get_allocator() == b.get_allocator(). Every iterator referring to an element in one container beforethe swap shall refer to the same element in the other container after the swap. It is unspecified whether aniterator with valuea.end() before the swap will have valueb.end() after the swap.


[8]ページ先頭

©2009-2026 Movatter.jp