This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
flat_foo::emplaceSection: 23.6.12.5 [flat.multiset.modifiers], 23.6.8.7 [flat.map.modifiers] Status: New Submitter: Arthur O'Dwyer Opened: 2024-12-09 Last modified: 2025-02-07
Priority: 3
View all issues with New status.
Discussion:
The usual pattern in 23 [containers] is that x.emplace(args...) has a precondition
(23.2.4 [sequence.reqmts] p20, 23.2.7.1 [associative.reqmts.general] p48) but no
Constraints element. That is, emplace is not SFINAE-friendly. And it has only the one overload,
so it doesn't need a constraint for purposes of overload resolution.
emplace: deque (23.3.5.4 [deque.modifiers]), list (23.3.11.4 [list.modifiers]),
vector (23.3.13.5 [vector.modifiers]), containers (23.2.4 [sequence.reqmts] p19),
associative containers (23.2.7.1 [associative.reqmts.general] p47),
unordered containers (23.2.8.1 [unord.req.general] p78), priority_queue (23.6.4.4 [priqueue.members] p5),
optional (22.5.3.4 [optional.assign] p29).
Constraints on emplace: flat_map (23.6.8.7 [flat.map.modifiers] p1),
flat_multiset (23.6.12.5 [flat.multiset.modifiers] p1), any (22.7.4.4 [any.modifiers] p1),
expected (22.8.6.4 [expected.object.assign] p16), variant (22.6.3.5 [variant.mod] p1).
I believe a Constraints element was accidentally copy-pasted from the spec of flat_map::insert(P&&)
— which does need the constraint because it's part of insert's large overload set — to
flat_map::emplace, and then from there to flat_multiset::emplace. The constraint is already (correctly) absent
from flat_set::emplace.
While we're touching this paragraph, also resolve the vague word "initializes" to "direct-non-list-initializes."
Editorially, pair<…> is a verbose way to spell the value_type of a flat_map; we should
be consistent and just say value_type.
[2025-02-07; Reflector poll]
Set priority to 3 after reflector poll. See reflector discussion for comments about proposed resolution.
Proposed resolution:
This wording is relative to N4993.
[Drafting note: 23.6.11.5 [flat.set.modifiers] is already OK as far as this issue is concerned: it has no wording for
[flat.multimap.modifiers] is already OK ditto: it does not exist. ]emplace.
Modify 23.6.12.5 [flat.multiset.modifiers] as indicated:
template<class... Args> iterator emplace(Args&&... args);-1- Mandates
-2- Effects: First, direct-non-list-initializes an objectConstraints:is_constructible_v<value_type, Args...>istrue.tof typevalue_typewithstd::forward<Args>(args)..., then insertstas if by:auto it = ranges::upper_bound(c, t, compare); c.insert(it, std::move(t));-3- Returns: An iterator that points to the inserted element.
Modify 23.6.8.7 [flat.map.modifiers] as indicated:
template<class... Args> pair<iterator, bool> emplace(Args&&... args);-1- Mandates
-2- Effects: First, direct-non-list-iConstraints:is_constructible_v<value_typeispair<key_type, mapped_type>, Args...>true.Initializes an objecttof typevalue_typewithpair<key_type, mapped_type>std::forward<Args>(args)...; if the map already contains an element whose key is equivalent tot.first,*thisis unchanged. Otherwise, equivalent to:auto key_it = ranges::upper_bound(c.keys, t.first, compare); auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); c.keys.insert(key_it, std::move(t.first)); c.values.insert(value_it, std::move(t.second));-3- Returns: The
boolcomponent of the returned pair istrueif and only if the insertion took place, and the iterator component of the pair points to the element with key equivalent tot.first.