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::emplace
Section: 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: 2024-12-14
Priority: Not Prioritized
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.9.4 [list.modifiers]),
vector
(23.3.11.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
.
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
.t
of typevalue_type
withstd::forward<Args>(args)...
, then insertst
as 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_type
ispair<key_type, mapped_type>, Args...>true
.Initializes an objectt
of typevalue_type
withpair<key_type, mapped_type>std::forward<Args>(args)...
; if the map already contains an element whose key is equivalent tot.first
,*this
is 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
bool
component of the returned pair istrue
if and only if the insertion took place, and the iterator component of the pair points to the element with key equivalent tot.first
.