I just have a quick question. I can't figure out the benefits of using std::next
over just adding the desired number of advancements to the pointer. A simple example:
int main()
{
int arr [] = {1, 2, 3, 4, 5};
cout << *(arr + 2) << ", "; //example 1
cout << *std::next(arr, 2) << endl; //example 2
return 0;
}
Output: 3, 3
Logically, example 1 should be quicker, since no function is called, etc. Also, in the instance in which I ran this code, if I added a number that would cause the pointer to be out of bounds (e.g. 7), the compiler would throw an error in example 1, but would happily go ahead and give me a memory address in example 2. This contradicted what I thought at first: that std::next
would give some kind of warning or something if the pointer was out of bounds.
Any enlightenment would be appreciated.
std::next
works with all iterator types. If you know you're dealing with an array, adding the value works fine. However, if you're writing a generic function that you want to work on different kinds of iterators, that poses a problem.
iter + 5
That operation is only defined for random access iterators.
std::next(iter, 5)
However, that operation is defined for forward iterators, which is a much broader category of iterator. In short, std::next
makes your code more generalized.
cplusplus.com has a full list of the operators supported by various iterator types, available here. As the chart on that page shows, all random access iterators are also forward but not nearly all forward iterators are random access. Things like linked lists will only work with std::next
Because std::next
is designed not only to work on raw pointers but on all iterators, therefore it's more versatile.
Your assumption is also false. Both approaches will most likely result in the same assembly when using reasonable optimization level. Again, c++ is designed to make such optimizations easier. In your example the underlying iterator type is a raw pointer, obviously, and it is quite trivial to deduce that the function call can be inlined.
EDIT:
As Matt said in his comment, there are more to iterators than just a fancy name and a template wrapper. There are data structures (containers) which do not reside in a contiguous memory segment (e.g. a map
or set
) they need to use more logic, to figure out the exact placement in memory. Iterators also wrap this, they provide a level of abstraction between algorithms and container.
So summing above points, using standard idioms helps in writing more robust code, i.e. supporting different types of containers (not caring about their memory layout) while keeping efficiency where possible due to quite smart compilers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With