Skip to content

Commit 1f92429

Browse files
committed
New issue from Hewill: "The standard library iterator adaptor does not handle iterator_category correctly"
1 parent 98b1659 commit 1f92429

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

xml/issue4237.xml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4237" status="New">
5+
<title>The standard library iterator adaptor does not handle <code>iterator_category</code> correctly</title>
6+
<section>
7+
<sref ref="[const.iterators.iterator]"/><sref ref="[range.adaptors]"/>
8+
</section>
9+
<submitter>Hewill Kang</submitter>
10+
<date>27 Mar 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
Currently, <code>basic_const_iterator</code>, and several range adaptors such as
16+
<code>filter_view</code>'s iterators provide <code>iterator_category</code> only when the
17+
underlying iterator models <code>forward_iterator</code>, implying that they expect those
18+
iterators should have a valid <code>iterator_category</code>.
19+
</p>
20+
<p>
21+
However, this is incorrect because being a <code>forward_iterator</code> does not
22+
necessarily mean it is a <i>Cpp17InputIterator</i>, it just means that it <i>probably</i>
23+
meets the syntactic requirements of <i>Cpp17InputIterator</i>.
24+
</p>
25+
<p>
26+
Any iterator that specializes <code>iterator_traits</code> and provides only
27+
<code>iterator_concept</code> without <code>iterator_category</code> is not a
28+
<i>Cpp17InputIterator</i>, for example, <code>common_iterator</code> with a
29+
<code>difference_type</code> of integer-class type.
30+
</p>
31+
<p>
32+
In this case, instantiating these iterator adaptors will result in a hard error because the
33+
<code>iterator_category</code> they expect does not exist. The following illustrates the
34+
problem (<a href="https://godbolt.org/z/j7x8bKzo4">demo</a>):
35+
</p>
36+
<blockquote><pre>
37+
#include &lt;iterator&gt;
38+
#include &lt;ranges&gt;
39+
40+
int main() {
41+
auto r = std::views::iota(0ULL)
42+
| std::views::take(5)
43+
| std::views::common;
44+
45+
static_assert(std::ranges::forward_range&lt;decltype(r)&gt;);
46+
47+
std::basic_const_iterator ci(r.begin()); // <span style="color:red;font-weight:bolder">'iterator_category': is not a member of 'std::iterator_traits'</span>
48+
49+
auto f = r | std::views::filter([](auto) { return true; });
50+
auto b = f.begin(); // <span style="color:red;font-weight:bolder">'iterator_category': is not a member of 'std::iterator_traits'</span>
51+
}
52+
</pre></blockquote>
53+
<p>
54+
I believe that checking if the underlying iterator is a <code>forward_iterator</code> is not an appropriate
55+
mechanism to provide <code>iterator_category</code>, but rather checking if its <code>iterator_traits</code>
56+
specialization provides <code>iterator_category</code>.
57+
</p>
58+
<p>
59+
This issue is somewhat related to LWG <iref ref="3763"/>, which is a further consideration after LWG
60+
<iref ref="3749"/> has been resolved.
61+
</p>
62+
</discussion>
63+
64+
<resolution>
65+
</resolution>
66+
67+
</issue>

0 commit comments

Comments
 (0)