Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5704dfd

Browse filesBrowse files
committed
New issue from Arthur: "Inconsistent constraints on flat_foo::emplace"
1 parent 04cd4c8 commit 5704dfd
Copy full SHA for 5704dfd

File tree

1 file changed

+106
-0
lines changed
Filter options

1 file changed

+106
-0
lines changed

‎xml/issue4180.xml

Copy file name to clipboard
+106Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4180" status="New">
5+
<title>Inconsistent constraints on <tt>flat_<i>foo</i>::emplace</tt></title>
6+
<section><sref ref="[flat.multiset.modifiers]"/><sref ref="[flat.map.modifiers]"/></section>
7+
<submitter>Arthur O'Dwyer</submitter>
8+
<date>09 Dec 2024</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
The usual pattern in <sref ref="[containers]"/> is that `x.emplace(args...)` has a precondition
14+
(<sref ref="[sequence.reqmts]"/> p20, <sref ref="[associative.reqmts.general]"/> p48) but no
15+
<i>Constraints</i> element. That is, `emplace` is not SFINAE-friendly. And it has only the one overload,
16+
so it doesn't need a constraint for purposes of overload resolution.
17+
<p/>
18+
No Constraints on `emplace`: `deque`, `list`, `vector`, `containers`, `associative containers`, `unordered containers`,
19+
`priority_queue`, `optional`.
20+
<p/>
21+
Constraints on `emplace`: `flat_map`, `flat_multiset`, `any`, `expected`, `variant`.
22+
<p/>
23+
I believe a <i>Constraints</i> element was accidentally copy-pasted from the spec of <tt>flat_map::insert(P&amp;&amp;)</tt>
24+
&mdash; which does need the constraint because it's part of `insert`'s large overload set &mdash; to
25+
`flat_map::emplace`, and then from there to `flat_multiset::emplace`. The constraint is already (correctly) absent
26+
`from flat_set::emplace`.
27+
<p/>
28+
While we're touching this paragraph, also resolve the vague word "initializes" to "direct-non-list-initializes."
29+
Editorially, <tt>pair&lt;&hellip;&gt;</tt> is a verbose way to spell the `value_type` of a `flat_map`; we should
30+
be consistent and just say `value_type`.
31+
</p>
32+
</discussion>
33+
34+
<resolution>
35+
<p>
36+
This wording is relative to <paper num="N4993"/>.
37+
</p>
38+
39+
<blockquote class="note">
40+
<p>
41+
[<i>Drafting note</i>: <sref ref="[flat.set.modifiers]"/> is already OK as far as this issue is concerned:
42+
it has no wording for `emplace`.
43+
<p/>
44+
[flat.multimap.modifiers] is already OK ditto: it does not exist. ]
45+
</p>
46+
</blockquote>
47+
48+
<ol>
49+
<li><p>Modify <sref ref="[flat.multiset.modifiers]"/> as indicated:</p>
50+
51+
<blockquote>
52+
<pre>
53+
template&lt;class... Args&gt; iterator emplace(Args&amp;&amp;... args);
54+
</pre>
55+
<blockquote>
56+
<p>
57+
-1- <i><ins>Mandates</ins><del>Constraints</del></i>: <tt>is_constructible_v&lt;value_type, Args...&gt;</tt> is <tt>true</tt>.
58+
<p/>
59+
-2- <i>Effects</i>: First, <ins>direct-non-list-</ins>initializes an object `t` of type `value_type` with
60+
<tt>std::forward&lt;Args&gt;(args)...</tt>, then inserts `t` as if by:
61+
</p>
62+
<blockquote><pre>
63+
auto it = ranges::upper_bound(c, t, compare);
64+
c.insert(it, std::move(t));
65+
</pre></blockquote>
66+
<p>
67+
-3- <i>Returns</i>: An iterator that points to the inserted element.
68+
</p>
69+
</blockquote>
70+
</blockquote>
71+
72+
</li>
73+
74+
<li><p>Modify <sref ref="[flat.map.modifiers]"/> as indicated:</p>
75+
76+
<blockquote>
77+
<pre>
78+
template&lt;class... Args&gt; pair&lt;iterator, bool&gt; emplace(Args&amp;&amp;... args);
79+
</pre>
80+
<blockquote>
81+
<p>
82+
-1- <i><ins>Mandates</ins><del>Constraints</del></i>: <tt>is_constructible_v&lt;<ins>value_type</ins><del>pair&lt;key_type, mapped_type&gt;</del>, Args...&gt;</tt>
83+
is <tt>true</tt>.
84+
<p/>
85+
-2- <i>Effects</i>: <ins>First, direct-non-list-i</ins><del>I</del>nitializes an object `t` of type
86+
<tt><ins>value_type</ins><del>pair&lt;key_type, mapped_type&gt;</del></tt> with <tt>std::forward&lt;Args&gt;(args)...</tt>;
87+
if the map already contains an element whose key is equivalent to `t.first`, `*this` is unchanged. Otherwise, equivalent to:
88+
</p>
89+
<blockquote><pre>
90+
auto key_it = ranges::upper_bound(c.keys, t.first, compare);
91+
auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
92+
c.keys.insert(key_it, std::move(t.first));
93+
c.values.insert(value_it, std::move(t.second));
94+
</pre></blockquote>
95+
<p>
96+
-3- <i>Returns</i>: The `bool` component of the returned pair is `true` if and only if the insertion took place, and
97+
the iterator component of the pair points to the element with key equivalent to `t.first`.
98+
</p>
99+
</blockquote>
100+
</blockquote>
101+
102+
</li>
103+
</ol>
104+
</resolution>
105+
106+
</issue>

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.