std::prev() is a utility function in the C++ Standard Library that returns a new iterator moved backward by a specified number of positions. Unlike manually decrementing an iterator, std::prev() provides a safer and more readable way to move backward through a sequence.
- Returns a new iterator without modifying the original iterator.
- Works with bidirectional and random-access iterators.
Example: Using std::prev()
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
vector<int> v = {10, 20, 30, 40, 50};
auto it = prev(v.end(), 2);
cout << *it;
return 0;
}
Output
40
Explanation: std::prev() returns an iterator pointing two positions before v.end(). The original iterator remains unchanged.
Syntax
template <class BidirectionalIterator> BidirectionalIterator prev(
BidirectionalIterator it,
typename iterator_traits< BidirectionalIterator>::difference_type n = 1);
Parameters
- it: Iterator to the base position.
- n: Number of positions by which the iterator should be moved backward. The default value is 1.
Return Value: Returns an iterator pointing to the element that is n positions before the given iterator.
Working of std::prev()
The implementation of std::prev() depends on the iterator category:
- Bidirectional Iterators: Moves backward one position at a time using the decrement (--) operator.
- Random-Access Iterators: Uses iterator arithmetic (+ or -) and moves in constant time.
Note: std::prev() requires at least a bidirectional iterator and cannot be used with input or forward iterators.
Example 1: Copying a Subrange Using std::prev()
#include <iostream>
#include <deque>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
deque<int> v1 = {1, 2, 3, 4, 5, 6, 7};
deque<int> v2 = {8, 9, 10};
auto first = v1.begin();
auto last = prev(v1.end(), 3);
copy(first, last, back_inserter(v2));
cout << "v2 = ";
for (auto x : v2)
cout << x << " ";
return 0;
}
Output
v2 = 8 9 10 1 2 3 4
Explanation: std::prev(v1.end(), 3) returns an iterator pointing three positions before the end of the container, allowing us to copy only a selected range.
Example 2: Moving Backward in a std::list
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
int main()
{
list<int> l = {1, 2, 3, 7, 8, 9};
auto it = prev(l.end(), 2);
cout << *it;
return 0;
}
Output
8
Explanation: Since std::list supports bidirectional iterators but not arithmetic operations, std::prev() provides a convenient way to move backward by multiple positions.
Advantages of Using std::prev()
std::prev() provides a convenient and readable way to move iterators backward.
- Returns a new iterator while preserving the original iterator.
- Works with bidirectional and random-access iterators.
- Simplifies backward traversal in containers such as list.
- Improves code readability compared to manually decrementing iterators.
Time Complexity
| Iterator Category | Time Complexity |
|---|---|
| Bidirectional Iterator | O(n) |
| Random Access Iterator | O(1) |
Using std::next() as an Alternative to std::prev()
std::next() can also be used to move an iterator backward by passing a negative value, provided the iterator supports bidirectional traversal.
auto it1 = std::prev(v.end(), 3);
auto it2 = std::next(v.end(), -3);
Both it1 and it2 point to the same element.
Note: Although std::next() can achieve the same result, std::prev() is generally preferred when the intent is specifically to move an iterator backward, as it improves code readability.
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
vector<int> v = {1,2,3,4,5,6,7};
auto it = next(v.end(), -3);
cout << *it;
return 0;
}
Output
5
However, std::prev() is generally preferred when the intent is specifically to move backward because it makes the code easier to understand.
std::prev() vs std::advance()
| std::prev() | std::advance() |
|---|---|
| Returns a new iterator | Modifies the original iterator |
| Does not change the original iterator | Changes the original iterator |
| Returns the advanced iterator | Returns void |
| Used for backward movement | Used for both forward and backward movement |
Applications of std::prev()
std::prev() is commonly used when working with bidirectional and random-access iterators.
- Accessing elements before a given position.
- Traversing list and other bidirectional containers.
- Selecting subranges of containers.
- Writing generic iterator-based algorithms.