Consider following code:
#include <string_view>
struct Iter
{
Iter() {}
Iter(std::string_view) {}
Iter begin() const
{
return *this;
}
};
It's a stripped down iterator, which is supposed to be used as for (auto x : Iter(...))
(exactly the same as fs::directory_iterator
). I've removed end()
and all the overloaded operators for brevity, since they don't affect the error.
This code compiles with -std=c++20
(with both GCC and Clang), but once I switch to -std=c++2b
, GCC and Clang with libstdc++ reject it, while Clang with libc++ still accepts it.
Here's the gist of the error:
iterator_concepts.h:945:6: error: exception specification of 'operator()<Iter>' uses itself
...
string_view:153:7: note: while checking the satisfaction of concept 'contiguous_range<const Iter &>' requested here
...
string_view:153:15: note: while substituting template arguments into constraint expression here
&& ranges::contiguous_range<_Range>
^~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:16: note: while checking constraint satisfaction for template 'basic_string_view<const Iter &, Iter>' required here
return *this;
^
<source>:10:16: note: in instantiation of function template specialization 'std::basic_string_view<char>::basic_string_view<const Iter &, Iter>' requested here
The error doesn't happen if the function isn't named begin
. Apparently return *this;
considers the string_view
constructor, which checks some concepts for Iter
, which includes checking the begin
itself.
What is going on and how do I fix this error?
Reported a bug for libstdc++.
This code compiles with -std=c++20 (with both GCC and Clang), but once I switch to -std=c++2b, GCC and Clang with libstdc++ reject it, while Clang with libc++ still accepts it.
Clang 14 with libstdc++ fails to compile it because Clang 14 had a buggy implementation of concepts and cannot compile GCC's <ranges>
header. Clang 15 with a recent version of libstdc++ compiles it OK.
GCC 12.1 failed to compile due to a cycle in constraint checks for one of string_view
's constructors. GCC 12.2 compiles OK, because it includes the change from P2499R0 "string_view
range constructor should be explicit
".
tl;dr C++23 was still under development in January 2022 and support was patchy.