This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.

### 2177. Requirements on `Copy/MoveInsertable`

Section: 22.2.1 [container.requirements.general] Status: C++14 Submitter: Loïc Joly Opened: 2012-08-10 Last modified: 2017-09-07

Priority: Not Prioritized

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

View all issues with C++14 status.

Discussion:

See also discussion following c++std-lib-32883 and c++std-lib-32897.

The requirements on `CopyInsertable` and `MoveInsertable` are either incomplete, or complete but hard to figure out.

From e-mail c++std-lib-32897:

Pablo Halpern:

I agree that we need semantic requirements for all of the `*Insertable` concepts analogous to the requirements we have on similar concepts.

Howard Hinnant:

I've come to believe that the standard is actually correct as written in this area. But it is really hard to read. I would have no objection whatsoever to clarifications to `CopyInsertable` as you suggest (such as the post-conditions on `v`). And I do agree with you that the correct approach to the clarifications is to confirm that `CopyInsertable` implies `MoveInsertable`.

[2012, Portland: Move to Tentatively Ready]

Move to Tentatively Ready by unanimous consent.

[2013-04-20 Bristol]

Proposed resolution:

This wording is relative to N3376.

1. Edit 22.2.1 [container.requirements.general] p13 as indicated:

   > -13- […] Given a container type `X` having an `allocator_type` identical to `A` and a `value_type` identical to `T` and given an lvalue `m` of type `A`, a pointer `p` of type `T*`, an expression `v` of type (possibly `const`) `T`, and an rvalue `rv` of type `T`, the following terms are defined. If `X` is not allocator-aware, the terms below are defined as if `A` were `std::allocator<T>` — no allocator object needs to be created and user specializations of `std::allocator<T>` are not instantiated:

   > - `T` is `DefaultInsertable` into `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p);

   > - An element of `X` is default-inserted if it is initialized by evaluation of the expression

   >   >     allocator_traits<A>::construct(m, p);

   >   where `p` is the address of the uninitialized storage for the element allocated within `X`.

   > - `T` is `CopyMoveInsertable` into `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, rv);

   >   and when evaluated the following postconditions hold: The value of `*p` is equivalent to the value of `rv` before the evaluation. [Note: `rv` remains a valid object. Its state is unspecified — end note]

   > - `T` is `MoveCopyInsertable` into `X` means that, in addition to satisfying the `MoveInsertable` requirements, the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, rv);

   >   and when evaluated the following postconditions hold: The value of `v` is unchanged and is equivalent to `*p`.

   > - `T` is `EmplaceConstructible` into `X` from `args`, for zero or more arguments `args`, means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, args);

   > - `T` is `Erasable` from `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::destroy(m, p);

   > [Note: A container calls `allocator_traits<A>::construct(m, p, args)` to construct an element at `p` using `args`. The default construct in `std::allocator` will call `::new((void*)p) T(args)`, but specialized allocators may choose a different definition. — end note]