Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to always specify the range in STL's algorithm functions explicitly, even if I want to work on the whole container?

When using STL's functions like sort() or min_element() I always have to specify the range by begin and end explicitly:

void range_example() {     std::vector<int> list = {7, 3, 9, 1, 5, 2};     auto found_element = std::min_element(list.begin(), list.end());     std::cout << *found_element << std::endl; } 

This makes sense if I intend to work only on part of my container, but more often I need the functions to work on the whole container. Is there a reason why there isn't an overloaded function that allows for this:

std::vector<int> list = {7, 3, 9, 1, 5, 2}; auto found_element = std::min_element(list); 

Is there a way to accomplish a function call for the total range of a container that I have overlooked?

EDIT: I'm aware that I can encapsulate that in a function myself, but because this must be done for all functions I'd like to avoid that if there is a better way.

like image 352
grefab Avatar asked Aug 19 '15 07:08

grefab


People also ask

What is range in algorithm?

You can think of a range as two iterators that refer to the beginning and end of a group of elements that you can iterate over. Because all containers support iterators, every container can be thought of as a range. Since all algorithms from Boost.

How do you write a range algorithm?

auto numbers = std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; auto rotatedNumbers = std::vector<int>{}; std::rotate_copy(begin(numbers), begin(numbers) + 3, end(numbers), back_inserter(rotatedNumbers)); After executing the above code, rotatedNumbers contains {3, 4, 5, 6, 7, 8, 9, 0, 1, 2} .


2 Answers

This is because STL algorithms are container-independent. Iterators provide a uniform way for them to work, with the only limitation being what are the guarantees this algorithm requires from these iterators.

For example, if you want to do a linear search for min_element(), you only need forward iterators (i.e. they only have to support operator++). So, you can write one simple templated implementation that will work with essentially every container, despite how the container is implemented under the hood.

You could overload functions to take only the container and apply begin() and end() on them, but this would mean that you have one more interface to remember.

Edit

I suppose there are a few other arguments that could be made. Since STL was all about mathematical beauty and emphasis that algorithms are separate from containers, always passing iterators would reinforce this notion.

On the other hand, in terms of the C++ language as a whole, one of the main goals of Stroustrup was to educate developers. The full power of STL algorithms comes from the ability to pass arbitrary iterator ranges, but most of the time you want to operate on the whole container. If you provided overloads for the whole container, it could be argued that a large number of people would never bother to learn to use range versions, because it would be precisely those versions that would fall into "another interface to remember" category.

like image 34
Maksim Solovjov Avatar answered Sep 23 '22 01:09

Maksim Solovjov


Most of the time, the standard library is designed to provide the minimal interface necessary to accomplish all the tasks required, i.e. it tries to avoid interface bloat. You can operate on a whole container when the algorithm accepts a pair of iterators, but you could not operate on a subrange if the algorithm accepted a container. So the iterator pair is more fundamental, and so that's what the standard library provides. Convenience functions are usually not included.

However, you're certainly not the first person to think this way, and there's the entire Boost.Range library devoted to treating a range (both a container and an arbitrary range) as a single entity instead of a pair of iterators.

There is also a formal proposal to incorporate Eric Niebler's range library in a future version of the C++ standard library.

like image 123
Angew is no longer proud of SO Avatar answered Sep 23 '22 01:09

Angew is no longer proud of SO