Why do std :: algorithm work directly and with containers?

Possible duplicate:
STL algorithms taking the whole container, not .begin (), end () like arg?

I studied some algorithms, and I wonder why some of them also do not have the variations that the container accepts.

For example, find can take a value in a container, and the algorithm can use an internal iterator over the container, calling begin and end container. The same thing with unique_copy , where it seems to me more useful to pass the container, and the algorithm uses push_back instead of requiring an iterator, where I would have to resize the array to the maximum number of elements. for_each is another example.

I'm sure there are good reasons that I don’t know about?

+6
source share
3 answers

I see two main reasons:

  • Adding overloads for containers would more than double the number of functions: for each algorithm that accepts only one range, overloads will be doubled. However, for something like std::copy() you have two ranges, each of them independently wants to specify either as a range (the correct abstraction is not containers, BTW, but rather rangers) or a couple of iterators, which makes it already 4 overload.
  • As soon as ranges enter the image, it is not clear what needs to be returned. Your example uses std::find() , which explicitly returns an iterator when it receives iterators as arguments. When a range is given, it may actually be much wiser to return a different range. To aggravate the situation, if at first you do not have one range of passage (for example, something is read from the stream), there is even a choice of two different ranges, i.e. Start searching for an object and find the object to the end. Another dimension may be the choice of obtaining a copy of the selected range, rather than the range limited by iterators.

When the STL was originally offered, it was considered Crazy Talk first! Trying to convince people to open another large jar of worms to manage the ranges properly could easily destroy the whole idea. Then the following question arises: why has this not changed? ... and there are two answers to this question:

  • I did not offer a modified interface, although the draft version was considered reasonable when I submitted it to the Library Working Group. However, the proposal that I set out was not greeted with great enthusiasm. In addition, at that time I had no idea how to really implement the interface that I expected with reasonable effort (with the capabilities of C ++ 2011 I know how to do this). I started writing a description of the new STL interface , but even this is incomplete, and I have not been able to find the time to work on this recently.
  • Although the algorithms, in my opinion, are the right ways, many people knowingly do not use them. I have discovered cases where people have replaced the use of algorithms because it is said that it is “more readable” to write a loop that performs an operation than calling an algorithm. Unfortunately, this is indeed even true in some cases, because the function objects involved are simply disgusting. Given that few seem to be using algorithms, there seems to be little incentive to change them.
+13
source

If you want to put the result in a container without first selecting the elements, use the insert iterator. For instance:

 std::vector<int> elements; // ... std::vector<int> uniqueElements; std::unique_copy(elements.begin(), elements.end(), std::back_inserter(uniqueElements)); 
+3
source

Algorithms that take iterators are the most common goal. There is nothing stopping you from creating your own convenience functions that call standard algorithms with the appropriate parameters.

+2
source

Source: https://habr.com/ru/post/925494/


All Articles