-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Open
Labels
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.rangesIssues related to `<ranges>`Issues related to `<ranges>`
Description
llvm-project/libcxx/include/__ranges/to.h
Lines 112 to 124 in 6c062af
for (auto&& __ref : __range) { | |
using _Ref = decltype(__ref); | |
if constexpr (requires { __result.emplace_back(std::declval<_Ref>()); }) { | |
__result.emplace_back(std::forward<_Ref>(__ref)); | |
} else if constexpr (requires { __result.push_back(std::declval<_Ref>()); }) { | |
__result.push_back(std::forward<_Ref>(__ref)); | |
} else if constexpr (requires { __result.emplace(__result.end(), std::declval<_Ref>()); }) { | |
__result.emplace(__result.end(), std::forward<_Ref>(__ref)); | |
} else { | |
static_assert(requires { __result.insert(__result.end(), std::declval<_Ref>()); }); | |
__result.insert(__result.end(), std::forward<_Ref>(__ref)); | |
} | |
} |
Range-based for loop is not guaranteed to be well-formed for input_range
as it does not extract iterator-pair through ranges::begin
/ranges::end
:
https://godbolt.org/z/Kc3dsvnfW
#include <ranges>
struct Vector {
void push_back(int);
};
struct OnlyADLRange {
void begin() = delete;
void end() = delete;
friend int* begin(OnlyADLRange&);
friend int* end(OnlyADLRange&);
};
int main() {
std::ranges::contiguous_range auto r = OnlyADLRange{};
auto v = r | std::ranges::to<Vector>(); // only well-formed in libstdc++
}
Metadata
Metadata
Assignees
Labels
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.rangesIssues related to `<ranges>`Issues related to `<ranges>`
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
[-]`<ranges>`: `ranges::to` use range-based for loops in append branches[/-][+][libc++] `<ranges>`: `ranges::to` use range-based for loops in append branches[/+]ranges::to
with ADL-onlybegin
/end
#119161hewillk commentedon Dec 9, 2024
range_formatter
have similar issues:llvm-project/libcxx/include/__format/range_formatter.h
Lines 197 to 201 in 4228a6e
hewillk commentedon Dec 9, 2024
It looks like libc++ extensively uses range-for loops to iterate over ranges when implementing P1206, so this should be something that can be modified uniformly (if worth it).
frederick-vs-ja commentedon Dec 9, 2024
I think I can fix these issues (if wanted). But they mean that we can't traverse a
range
using range-for
in generic code, which sounds weird.philnik777 commentedon Dec 9, 2024
Yeah, I think there should be an LWG or CWG issue about this. Not being able to iterate a range with a range-based for loop sounds a lot like a design flaw to me.
jwakely commentedon Sep 12, 2025
I think we should change the
std::range
concept to say that it is not modelled by silly types where range-basedfor
andranges::for_each
disagree. That means implementers don't need to bend over backwards to support such types, the types are just bad and should feel bad. Maybe your program will still "work" if you use such types where arange
is required, for some value of "work", but formally it will be ill-formed; no diagnostic required.jwakely commentedon Sep 12, 2025
Most importantly, declaring such types bad means no changes needed to implementations. We can just keep doing what we do.
frederick-vs-ja commentedon Sep 12, 2025
Looks weird but comprehensible to me. I thought that it was intended that the
range
concept should be stricter than range-for
and these types shouldn't satisfyrange
. But then I sadly found that the intent might be somehow unachievable (or at least couldn't be reasonably achieved)...hewillk commentedon Sep 13, 2025
I'd actually love to see an LWG on this.
For example, add a semantic requirement for the
range
concept thatranges::for_each(rg, [](auto&& e){})
must be equivalent tofor (auto&& e : rg)
.jwakely commentedon Sep 17, 2025
There are currently types that can't be used with range-based
for
at all, so in order to be able to use range-basedfor
to iterate over arange
we would need core language changes to allowfor
to work with all types that modelrange
. Which could be difficult to get through the committee.