Date
2015-02-06.21:06:04
Message id
7229

Content

The "Requires:" clause for the operator[] for the unordered_map and map, are defining separate requirements for insertability into container of mapped_type and key_type.

[map.access] p2: // T& operator[](const key_type& x);

Requires: key_type shall be CopyInsertable and mapped_type shall be DefaultInsertable into *this.

[map.access] p6: // T& operator[](key_type&& x)

Requires: mapped_type shall be DefaultInsertable into *this.

[unord.map.elem] p1: // mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k);

Requires: mapped_type shall be DefaultInsertable into *this. For the first operator, key_type shall be CopyInsertable into *this. For the second operator, key_type shall be MoveConstructible.

Definition of the appropriate requirements: [container.requirements.general] p15.

T is DefaultInsertable into X means that the following expression is well-formed: //p15.1

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

T is MoveInsertable into X means that the following expression is well-formed: //p15.3

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

T is CopyInsertable into X means that, in addition to T being MoveInsertable into X, the following expression is well-formed: //p15.4

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

In the context of above definition the requirement "key_type shall be CopyInsertable into *this" would mean that the key element of the pair<const key_type, mapped_type> (value_type of the map) should be constructed using separate call to the construct method, the same applies for the mapped_type. Such behavior is explicitly prohibited by [container.requirements.general] p3.

For the components affected by this sub-clause that declare an allocator_type, objects stored in these components shall be constructed using the allocator_traits<allocator_type>::construct function and destroyed using the allocator_traits<allocator_type>::destroy function (20.7.8.2). These functions are called only for the container's element type, not for internal types used by the container.

It clearly states that element_type of the map, must be constructed using allocator for value type, which disallows using of separate construction of first and second element, regardless of the fact if it can be actually performed without causing undefined behavior.

That means that the MoveInsertable and similar requirements may only be expressed in terms of value_type, not its members types.