std::prev in C++

std::prev returns an iterator pointing to the element after being advanced by certain no. of positions in the reverse direction. It is defined inside the header file .

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.

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to demonstrate std::prev
#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::prev
    deque<int>::iterator i2;
    i2 = std::prev(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;
}

chevron_right


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.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to demonstrate std::prev
    #include <iostream>
    #include <iterator>
    #include <list>
    #include <algorithm>
    using namespace std;
    int main()
    {
        // Declaring first container
        list<int> v1 = { 1, 2, 3, 7, 8, 9 };
      
        // Declaring second container
        list<int> v2 = { 4, 5, 6 };
      
        list<int>::iterator i1;
        i1 = v1.begin();
        // i1 points to 1 in v1
      
        list<int>::iterator i2;
        // i2 = v1.end() - 3;
        // This cannot be used with lists
        // so use std::prev for this
      
        i2 = std::prev(v1.end(), 3);
      
        // Using std::copy
        std::copy(i1, i2, std::back_inserter(v2));
        // v2 now contains 4 5 6 1 2 3
      
        // Displaying v1 and v2
        cout << "v1 = ";
      
        int i;
        for (i1 = v1.begin(); i1 != v1.end(); ++i1) {
            cout << *i1 << " ";
        }
      
        cout << "\nv2 = ";
        for (i1 = v2.begin(); i1 != v2.end(); ++i1) {
            cout << *i1 << " ";
        }
      
        return 0;
    }

    chevron_right

    
    

    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.

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


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.

This article is contributed by Mrigendra Singh. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up


Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.