3339. Move-constructed empty-container capacity

Section: 27.4.3 [basic.string], 23.3.11 [vector], 23.5.3 [unord.map], 23.5.6 [unord.set], 23.2.2 [container.requirements.general] Status: New Submitter: Nathan Myers Opened: 2019-11-17 Last modified: 2020-09-06

Priority: 3

View other active issues in [basic.string].

View all other issues in [basic.string].

View all issues with New status.

Discussion:

The Standard leaves unspecified the capacity() of a string or vector, and bucket_count() of an unordered_(multi)set or unordered_(multi)map, constructed by move from an empty other.

For a non-empty other, normative language in the Standard constrains the new object to use (mostly) the same storage as the other, by way of lifetime of iterators and pointers to elements.

For an empty other, there can be no such pointers or iterators. However, the empty container may have a non-zero capacity() or bucket_count(), and having reserved storage there, one naturally expects that storage to be delivered to the new object in the same way as if it had elements.

Existing implementations, in fact, do move storage to the new container, provided it can be deallocated using the new object's allocator. It is likely that existing programs have come to depend on this behavior.

The resolution proposed is to add language to the Standard specifying that, if the allocators of the existing and new container objects are compatible, the storage of the new object is the same as of the old, so that no allocations or deallocations are performed in the process, as existing implementations in fact do.

This appears to affect only string, vector, unordered_set, unordered_multiset, unordered_map, and unordered_multimap, but any new container types may also need similar attention.

Note that in the case of the hashed containers, the array of buckets appears not to be required to be moved, even when elements contained are. This seems to be a similar oversight; extant implementations do move the bucket array. The resolution should cover this case as well.

It is expected and intended that the proposed resolution does not require changes to the behavior of implementations.

See also LWG 2321 and P0966R1.

[2019-11-30 Issue Prioritization]

Priority to 3 after reflector discussion.

Proposed resolution: