5 ms·
> why are "ranges" needed for that? They aren't, but without ranges, things that accept iterators are more general than things that accept only containers (e.g
by MaulingMonkey 8y ago
> why are "ranges" needed for that?
They aren't, but without ranges, things that accept iterators are more general than things that accept only containers (e.g. you can't iterate over half a container without a range, iterators, or copying to another container through other means defeating which would defeat the whole point.)
As such it makes sense to have a generic range type first, then algorithms that operate on containers/ranges.
Additionally, if you can take a range<Iter> instead of a Container (I haven't even checked if C++20 algorithms do), you might get better error messages (e.g. "Xyz cannot be converted to a range" instead of "Xyz doesn't implement begin()").
> What took so long
Everything takes long in C++ standards land. I have no special insight into the actual workings of the standards committee, but I've always chalked it up to a combination of being extremely conservative about changes, made worse by past missteps burning them, and less than ideal foundations which already made C++ hard to parse, slow to compile, and inconsistent across compilers, and often not fully implemented.
It's not like there's been some giant technical hurdle across the board - boost::range has been around for well over a decade (in boost since 1.32.0 in 2004).
Faster iterating languages usually have a fresh start unencumbered by backwards compatibility concerns with large existing codebases, less cruft inherited from other languages (cough C cough), and a single official implementation which can be used to more quickly prove out good ideas and discard bad ones.
- Aardwolf 8y ago> They aren't, but without ranges, things that accept iterators are more general than things that accept only containers (e.g. you can't iterate over half a container without a range, iterators, or copying to another container through other means defeating which would defeat the whole point.) Yes but they could have provided both a single-container-parameter version and a two-iterator-parameter version of all those functions like sort and transform. Templates and SFINAE support that, and the single parameter one would call the two parameter one with .begin() and .end() for you. They should try to make the std library such that you type shorter code, not longer code, imho: longer expressions are less readable. But well, it looks like ranges mostly do that for the user side (except that it uses std::ranges:: instead of just std:: as prefix) so at least that's nice.
- MaulingMonkey 8y ago> Yes but they could have provided both a single-container-parameter version and a two-iterator-parameter version of all those functions like sort and transform. For my own libraries I'd skip the iterator accepting version. Implementing one range type is way easier / less prone to oversights and other mistakes than double implementing every algorithm. Or more than double implementing, if you need perfect forwarding for non-copyable functors without std::forward pre-C++11. Even though all they do is forward. SC++L doesn't get much choice since they started with iterators only, but even there, I'm not sure how much time skipping std::range saves you. You can't even take a plain C style array without either a range type, free-form std::begin/std::end, or the iterator variant.
- deleted 8y ago[deleted]
- int_19h 8y ago> and the single parameter one would call the two parameter one with .begin() and .end() for you. Doesn't work with arrays, since they don't have member functions.