Why does std::next default by 1, but std::advance does not?
3 answers
I have already made such a proposal to the C ++ Standardization Committee. I described this discrepancy in my forum in the subject std :: advance and std :: bitset - two simple sentences on the C ++ standard. The number of this sentence is # 4369 . Unfortunately, I did not follow the fate of this proposal. Formally, it was approved before the discussion, but, as always, there are people in the committee who consider only their own proposals to be the most important and jealously treat other proposals. Therefore, I now do not know what the fate of my proposal. But there are no obvious reasons for not making the default argument for the second parameter and I have not met any serious objections from other opponents.
These functions serve somewhat different purposes and have appeared for completely different reasons.
std::advanceis an old function (C ++ 98), which was intended to unify iterators of different categories in generic algorithms, and first of all in situations where the iterator has to be moved more than one step . With the pushing exactly one step, the operators++and--coped.std::advancewas executed in the form of a named function (and not operator overloading+=or-=) precisely in order to draw the user's attention to a potentially inefficient operation and thereby try to eliminate its unintended use. Similar reasons led to the appearance of the "pair" explicit functionstd::distance.std::nextandstd::prevare new functions (C ++ 11), created in particular in order to encapsulate the idiom of getting a neighboring iterator without modifying the current one . Considering that, in general, a binary operation+not applicable to an iterator, you cannot simply add and add to iterator1It it; ... foo(it + 1); // в общем случае - не сработаетFor iterators of class types in such a situation, the compact version works
foo(++It(it));but it is inapplicable to iterators of fundamental types, which in generic contexts forces to get an additional named variable, i.e. write out something like
It it_next = it; foo(++it_next);This is more cumbersome than we would like, and introduces an unnecessary named variable into the code.
The
std::advancefunction, if you pay attention to the features of its interface, cannot help us here. This is where thestd::nextandstd::prevfunctions come to the rescue, which hide such details.At the same time, their most sought-after purpose / use is to get the neighboring iterator. And the ability to specify a distance is only a natural extension of this functionality.
In other words, the answer to your question in the historical key sounds simple: std::advance was created specifically for shifting the iterator by more than 1 step , and std::next and std::prev instituted primarily for shifting exactly 1 step .
Also, considering that std::advance can work in both directions, it would be strange now to impose +1 on it as the default argument.
It may well be that if, initially, in C ++ 98, the std::advance function was entered with the interface
template< class InputIt, class Distance > InputIt advance( InputIt it, Distance n ); (Ie, with the transfer and return of the iterator "by value", and not with the transfer of the modified iterator "by reference"), today there would be no special need for std::next and std::prev . And if these functions would appear, it is possible without the "distance" parameter.
Why does
std::nextdefault by 1, butstd::advancedoes not?
Because std::next as std::prev clearly indicate the direction of the modification. And the presence of the default value is only a refinement of the step .
There is no sense in assigning the default modification for std::advance , since for this function the positive and negative offsets are "equal-significant". If you register a step, then it automatically equates to the residence of the default direction of the modification, which will not correspond to the abbreviation of the function.
- 3Make
advanceoffset of0for default, and all things :) - αλεχολυτ
nextif it promotes to any value? - user230240