std::prev in C++
std::prev returns an iterator pointing to the element after being advanced by certain number of positions in the reverse direction. It is defined inside the header file iterator. It returns a copy of the argument advanced by the specified amount in the backward direction. If it is a random-access iterator, the function uses just once operator + or operator – for advancing. Otherwise, the function uses repeatedly the increase or decrease operator (operator ++ or operator – -) on the copied iterator until n elements have been advanced. Syntax:
BidirectionalIterator prev (BidirectionalIterator it, typename iterator_traits::difference_type n = 1); it: Iterator to the base position. difference_type: It is the numerical type that represents distances between iterators of the BidirectionalIterator type. n: Total no. of positions by which the iterator has to be advanced. In the syntax, n is assigned a default value 1 so it will atleast advance by 1 position. Returns: It returns an iterator to the element n positions before it.
CPP
// C++ program to demonstrate std::next #include <iostream> #include <iterator> #include <deque> #include <algorithm> using namespace std; int main() { // Declaring first container deque< int > v1 = { 1, 2, 3, 4, 5, 6, 7 }; // Declaring another container deque< int > v2 = { 8, 9, 10 }; // Declaring an iterator deque< int >::iterator i1; // i1 points to 1 i1 = v1.begin(); // Declaring another iterator to store return // value and using std::next deque< int >::iterator i2; i2 = std::next(v1.end(), -3); // Using std::copy std::copy(i1, i2, std::back_inserter(v2)); // Remember, i1 stills points to 1 // and i2 points to 5 // v2 now contains 8 9 10 1 2 3 4 // Displaying v1 and v2 cout << "v1 = "; int i; for (i = 0; i < 7; ++i) { cout << v1[i] << " "; } cout << "\nv2 = "; for (i = 0; i < 7; ++i) { cout << v2[i] << " "; } return 0; } |
Output:
v1 = 1 2 3 4 5 6 7 v2 = 8 9 10 1 2 3 4
How can it be helpful ?
- Moving iterator in Lists: Since, lists support bidirectional iterators, which can be incremented only by using ++ and – – operator. So, if we want to advance the iterator by more than one position, then std::next and if we want to decrement the iterator, then std::prev can be extremely useful.
CPP
- Output:
v1 = 1 2 3 7 8 9 v2 = 4 5 6 1 2 3
- Explanation: Here, just look how if we want copy only a selected portion of the list, then we can make use of std::prev, as otherwise we cannot use any +=, -= operators with bidirectional iterators supported by lists. So, we used std::prev and directly moved the iterator backwards by three positions from the end.
Can we use std::next in place of std::prev ?
One common query that may arise with std::prev is that can std::next be also used with a negative argument to move the iterator in backward direction. Well, the answer is yes.
CPP
// C++ program to demonstrate std::next #include <iostream> #include <iterator> #include <deque> #include <algorithm> using namespace std; int main() { // Declaring first container deque< int > v1 = { 1, 2, 3, 4, 5, 6, 7 }; // Declaring another container deque< int > v2 = { 8, 9, 10 }; // Declaring an iterator deque< int >::iterator i1; // i1 points to 1 i1 = v1.begin(); // Declaring another iterator to store return // value and using std::next deque< int >::iterator i2; i2 = std::next(v1.end(), -3); // Using std::copy std::copy(i1, i2, std::back_inserter(v2)); // Remember, i1 stills points to 1 // and i2 points to 5 // v2 now contains 8 9 10 1 2 3 4 // Displaying v1 and v2 cout << "v1 = "; int i; for (i = 0; i < 7; ++i) { cout << v1[i] << " "; } cout << "\nv2 = "; for (i = 0; i < 7; ++i) { cout << v2[i] << " "; } return 0; } |
Output:
v1 = 1 2 3 4 5 6 7 v2 = 8 9 10 1 2 3 4
Explanation: So, we have just used std::next in place of std::prev and changed the second argument from 3 to -3 here and it still serves the same purpose. We can use std::next also, but there are two things that needs to be kept in mind:
- Since, std::next in their syntax have an argument as forward iterator, so if we want to use negative no. for advancing that iterator, then it should be at least a bidirectional iterator.
- Although, std::next can also be used, but std::prev() would be more readable when the intent is specifically to move backwards.
Contact Us