Title
Conditional copy/move in std::vector
Status
open
Section
[vector.capacity]
Submitter
Nikolay Ivchenkov

Created on 2012-05-08.00:00:00 last changed 17 months ago

Messages

Date: 2022-11-06.10:55:28

Proposed resolution:

This wording is relative to N4750.

The revised wording below uses the new Mandates: element introduced by adopting P0788R3 at the Rapperswil meeting 2018 and which will become a new term of art with Jonathan's omnibus paper throughout the Standard Library.

[container.requirements.general] Table 77 — Container requirements
Expression Return type Operational semantics Assertion/note/pre-/post-condition Complexity
X(a) Mandates: Syntactic requirements of T
is Cpp17CopyInsertable into X (see below).

Requires: T is Cpp17CopyInsertable into X (see below).
post: a == X(a).
linear
X u(a)
X u = a;
Mandates: Syntactic requirements of T
is Cpp17CopyInsertable into X (see below).

Requires: T is Cpp17CopyInsertable into X (see below).
post: u == a.
linear
... ... ... ... ...
r = a X& Mandates: Syntactic requirements of T
is Cpp17CopyInsertable into X (see below) and CopyAssignable.
Requires: T is Cpp17CopyInsertable into X and CopyAssignable.
post: r == a.
linear

[container.requirements.general] Table 80 — Allocator-aware container requirements
Expression Return type Operational semantics Assertion/note/pre-/post-condition Complexity
a = t X& Mandates: Syntactic requirements of T is
Cpp17CopyInsertable into X and CopyAssignable.
Requires: T is Cpp17CopyInsertable into X and CopyAssignable.
post: r == a.
linear

Date: 2022-11-15.00:00:00

[ 2022-11-06; Daniel comments ]

This issue has considerable overlap with LWG 3758.

Date: 2018-08-23.00:00:00

[ 2018-08-23 Batavia Issues processing. Priority to 3 ]

Changed CopyInsertable -> Cpp17CopyInsertable in the resolution.

Tim says that the wording is not quite right — it imposes additional requirements.

Date: 2018-06-15.00:00:00

[ 2018-06-12, Daniel provides revised wording ]

Previous resolution [SUPERSEDED]:

This wording is relative to N4606.

[container.requirements.general] Table 80 — Container requirements
Expression Return type Operational semantics Assertion/note/pre-/post-condition Complexity
X(a) Requires: T is CopyInsertable into X (see below)., otherwise this expression shall be ill-formed.
post: a == X(a).
linear
X u(a)
X u = a;
Requires: T is CopyInsertable into X (see below)., otherwise this expression shall be ill-formed.
post: u == a.
linear
... ... ... ... ...
r = a X& Requires: T is CopyInsertable into X and CopyAssignable, otherwise this expression shall be ill-formed.
post: r == a.
linear

[container.requirements.general] Table 83 — Allocator-aware container requirements
Expression Return type Operational semantics Assertion/note/pre-/post-condition Complexity
a = t X& Requires: T is CopyInsertable into X and CopyAssignable., otherwise this expression shall be ill-formed
post: r == a.
linear

Date: 2018-06-12.02:06:47

[ 2018-06 Rapperswil Wednesday issues processing ]

Daniel to provide updated wording.

Date: 2017-11-13.19:00:40

[ 2017-11 Albuquerque Saturday issues processing ]

There's a bunch of uses of "shall" here that are incorrect. Also, CopyInsertable contains some semantic requirements, which can't be checked at compile time, so 'ill-formed' is not possible for detecting that.

Date: 2017-11-07.04:03:15

[ 08-2016, Chicago ]

Fri PM: Move to Open

Date: 2016-08-02.19:38:28

[ 2016-08 Chicago ]

The problem does not appear to be as severe as described. The MoveInsertable requirements are consistently correct, but an issue may arise on the exception-safety guarantees when we check for is_copy_constructible_v<T>. The problem, as described, is typically for templates that appear to have a copy constructor, but one that fails to compile once instantiated, and so gives a misleading result for the trait.

In general, users should not provide such types, and the standard would not serve users well by trying to address support for such types. However, the standard should not be providing such types either, such as vector<unique_ptr<T>>. A possible resolution would be to tighten the constraints in Table 80 — Container Requirements, so that if the Requirements for the copy constructor/assingment operator of a container are not satisfied, that operation shall be deleted.

A futher problem highlighted by this approach is that there are no constraints on the copy-assignment operator, so that vector<unique_ptr<T>> should be CopyAssignable! However, we can lift the equivalent constraints from the Allocator-aware container requirements.

Date: 2012-05-08.00:00:00

There are various operations on std::vector that can cause elements of the vector to be moved from one location to another. A move operation can use either rvalue or const lvalue as argument; the choice depends on the value of !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value, where T is the element type. Thus, some operations on std::vector (e.g. 'resize' with single parameter, 'reserve', 'emplace_back') should have conditional requirements. For example, let's consider the requirement for 'reserve' in N3376 – [vector.capacity]/2:

Requires: T shall be MoveInsertable into *this.

This requirement is not sufficient if an implementation is free to select copy constructor when !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value evaluates to true. Unfortunately, is_copy_constructible cannot reliably determine whether T is really copy-constructible. A class may contain public non-deleted copy constructor whose definition does not exist or cannot be instantiated successfully (e.g., std::vector<std::unique_ptr<int>> has copy constructor, but this type is not copy-constructible). Thus, the actual requirements should be:

  • if !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value then T shall be CopyInsertable into *this;

  • otherwise T shall be MoveInsertable into *this.

Maybe it would be useful to introduce a new name for such conditional requirement (in addition to "CopyInsertable" and "MoveInsertable").

History
Date User Action Args
2022-11-06 10:55:28adminsetmessages: + msg12934
2018-08-24 13:31:33adminsetmessages: + msg10109
2018-06-12 19:27:00adminsetmessages: + msg9914
2018-06-12 02:06:47adminsetmessages: + msg9897
2017-11-13 19:00:40adminsetmessages: + msg9549
2016-08-06 21:12:20adminsetmessages: + msg8443
2016-08-06 21:12:20adminsetstatus: new -> open
2016-08-02 19:38:28adminsetmessages: + msg8343
2016-08-02 19:38:28adminsetmessages: + msg8342
2012-05-08 00:00:00admincreate