Created on 2024-12-09.00:00:00 last changed 7 days ago
Proposed resolution:
This wording is relative to N4993.
[Drafting note: [flat.set.modifiers] is already OK as far as this issue is concerned: it has no wording for `emplace`.
[flat.multimap.modifiers] is already OK ditto: it does not exist. ]
Modify [flat.multiset.modifiers] as indicated:
template<class... Args> iterator emplace(Args&&... args);-1- Mandates
-2- Effects: First, direct-non-list-initializes an object `t` of type `value_type` with std::forward<Args>(args)..., then inserts `t` as if by:Constraints: is_constructible_v<value_type, Args...> is true.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 [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_typepair<key_type, mapped_type>, Args...> is true.Initializes an object `t` of type value_typepair<key_type, mapped_type>with std::forward<Args>(args)...; if the map already contains an element whose key is equivalent to `t.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 is `true` if and only if the insertion took place, and the iterator component of the pair points to the element with key equivalent to `t.first`.
The usual pattern in [containers] is that `x.emplace(args...)` has a precondition ([sequence.reqmts] p20, [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.
No Constraints on `emplace`: `deque` ([deque.modifiers]), `list` ([list.modifiers]), `vector` ([vector.modifiers]), `containers` ([sequence.reqmts] p19), `associative containers` ([associative.reqmts.general] p47), `unordered containers` ([unord.req.general] p78), `priority_queue` ([priqueue.members] p5), `optional` ([optional.assign] p29). Constraints on `emplace`: `flat_map` ([flat.map.modifiers] p1), `flat_multiset` ([flat.multiset.modifiers] p1), `any` ([any.modifiers] p1), `expected` ([expected.object.assign] p16), `variant` ([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`.History | |||
---|---|---|---|
Date | User | Action | Args |
2024-12-14 15:46:49 | admin | set | messages: + msg14520 |
2024-12-09 00:00:00 | admin | create |