-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
bugSomething isn't workingSomething isn't workingfixedSomething works now, yay!Something works now, yay!rangesC++20/23 rangesC++20/23 ranges
Description
STL/stl/inc/__msvc_ranges_to.hpp
Lines 1124 to 1136 in 89ca073
| for (auto&& _Elem : _Range) { | |
| using _ElemTy = decltype(_Elem); | |
| if constexpr (_Can_emplace_back<_Container, _ElemTy>) { | |
| _Cont.emplace_back(_STD forward<_ElemTy>(_Elem)); | |
| } else if constexpr (_Can_push_back<_Container, _ElemTy>) { | |
| _Cont.push_back(_STD forward<_ElemTy>(_Elem)); | |
| } else if constexpr (_Can_emplace_end<_Container, _ElemTy>) { | |
| _Cont.emplace(_Cont.end(), _STD forward<_ElemTy>(_Elem)); | |
| } else { | |
| _STL_INTERNAL_STATIC_ASSERT(_Can_insert_end<_Container, _ElemTy>); | |
| _Cont.insert(_Cont.end(), _STD forward<_ElemTy>(_Elem)); | |
| } | |
| } |
To save the include overhead of ranges::for_each, MSVC-STL uses range-based for loop to iterate over the range. However, this is not guaranteed to be well-formed as the former does not extract iterators and sentinels through ranges::begin/ranges::end.
A disgusting and contrived case could be:
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++
}Above, only libstdc++ explicitly uses ranges::begin/ranges::end to get iterators-pair and iterates over the ranges via a while loop so there is no issue.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingfixedSomething works now, yay!Something works now, yay!rangesC++20/23 rangesC++20/23 ranges