Skip to content

Commit ccc0240

Browse files
committed
New issue from Hewill: "The helper lambda of std::erase for list should specify return type as bool"
1 parent 638bb45 commit ccc0240

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

xml/issue4135.xml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4135" status="New">
5+
<title>The helper lambda of <code>std::erase</code> for <code>list</code> should specify return type as
6+
<code>bool</code></title>
7+
<section><sref ref="[forward.list.erasure]"/><sref ref="[list.erasure]"/></section>
8+
<submitter>Hewill Kang</submitter>
9+
<date>07 Aug 2024</date>
10+
<priority>99</priority>
11+
12+
<discussion>
13+
<p>
14+
<code>std::erase</code> for <code>list</code> is specified to return
15+
<code>erase_if(c, [&amp;](auto&amp; elem) { return elem == value; })</code>.
16+
However, the template parameter <code>Predicate</code> of <code>erase_if</code> only requires that the
17+
type of <code>decltype(pred(...))</code> satisfies <code><i>boolean-testable</i></code>, i.e., the
18+
return type of <code>elem == value</code> is not necessarily <code>bool</code>.
19+
<p/>
20+
This means it's worth explicitly specifying the lambda's return type as <code>bool</code> to avoid some
21+
pedantic cases (<a href="https://godbolt.org/z/xPvYYnvY6">demo</a>):
22+
</p>
23+
<blockquote><pre>
24+
#include &lt;list&gt;
25+
26+
struct Bool {
27+
Bool(const Bool&amp;) = delete;
28+
operator bool() const;
29+
};
30+
31+
struct Int {
32+
Bool&amp; operator==(Int) const;
33+
};
34+
35+
int main() {
36+
std::list&lt;Int&gt; l;
37+
std::erase(l, Int{}); // <span style="color:#C80000;font-weight:bold">unnecessary hard error</span>
38+
}
39+
</pre></blockquote>
40+
</discussion>
41+
42+
<resolution>
43+
<p>
44+
This wording is relative to <paper num="N4988"/>.
45+
</p>
46+
47+
<ol>
48+
49+
<li><p>Modify <sref ref="[forward.list.erasure]"/> as indicated:</p>
50+
51+
<blockquote>
52+
<pre>
53+
template&lt;class T, class Allocator, class U = T&gt;
54+
typename forward_list&lt;T, Allocator&gt;::size_type
55+
erase(forward_list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
56+
</pre>
57+
<blockquote>
58+
<p>
59+
-1- <i>Effects</i>: Equivalent to:
60+
<code>return erase_if(c, [&amp;](<ins>const</ins> auto&amp; elem) <ins>-&gt; bool</ins> { return elem == value; });</code>
61+
</p>
62+
</blockquote>
63+
</blockquote>
64+
</li>
65+
66+
<li><p>Modify <sref ref="[list.erasure]"/> as indicated:</p>
67+
68+
<blockquote>
69+
<pre>
70+
template&lt;class T, class Allocator, class U = T&gt;
71+
typename list&lt;T, Allocator&gt;::size_type
72+
erase(list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
73+
</pre>
74+
<blockquote>
75+
<p>
76+
-1- <i>Effects</i>: Equivalent to:
77+
<code>return erase_if(c, [&amp;](<ins>const</ins> auto&amp; elem) <ins>-&gt; bool</ins> { return elem == value; });</code>
78+
</p>
79+
</blockquote>
80+
</blockquote>
81+
</li>
82+
83+
</ol>
84+
</resolution>
85+
86+
</issue>

0 commit comments

Comments
 (0)