Difference between std::next and std::advance in C++
In this article, we will discuss the difference between std::next() and std::advance() in C++. But before discussing the differences, we must know about the std::next() and std::advance().
What is Std::next()?
- A straightforward utility method called std::next() returns an iterator pointing to the element that is a given number of positions away from the provided iterator.
- Instead of altering the initial iterator, it returns a new iterator that points to the desired location.
Syntax:
It has the following syntax:
template<class ForwardIt>
ForwardIt next(ForwardIt it, typename std::iterator_traits<ForwardIt>::difference_type n = 1);
Example code:
std::vector<int> numbers = {1, 2, 3, 4, 5};
auto it = numbers.begin();
auto nextIt = std::next(it, 2); // points to the element at index 2 (value 3)
What is Std::advance?
- A more versatile function called std::advance advances the provided iterator by a predetermined number of positions, altering it.
- It doesn't return a new iterator; instead, it makes changes to the input iterator directly.
Syntax:
It has the following syntax:
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n);
Example code:
std::list<int> myList = {1, 2, 3, 4, 5};
auto it = myList.begin();
std::advance(it, 3); // it now points to the element at index 3 (value 4)
Example 1:
Let's take an example to illustrate the use of std::next() and std::advance() function in C++.
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
int main() {
// Example using std::next
std::cout << "Example using std::next:" << std::endl;
std::vector<int> numbers = {1, 2, 3, 4, 5};
auto it_next = std::next(numbers.begin(), 2);
std::cout << "Original vector: ";
for (const auto& num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "Iterator after std::next: " << *it_next << std::endl << std::endl;
// Example using std::advance
std::cout << "Example using std::advance:" << std::endl;
std::list<int> myList = {1, 2, 3, 4, 5};
auto it_advance = myList.begin();
std::advance(it_advance, 3);
std::cout << "Original list: ";
for (const auto& num : myList) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "Iterator after std::advance: " << *it_advance << std::endl;
return 0;
}
Output:
Example using std::next:
Original vector: 1 2 3 4 5
Iterator after std::next: 3
Example using std::advance:
Original list: 1 2 3 4 5
Iterator after std::advance: 4
Example 2:
Let's take another example to illustrate the use of std::next() and std::advance() function in C++.
#include <iostream>
#include <map>
#include <iterator>
int main() {
// Example using std::next
std::cout << "Example using std::next:" << std::endl;
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
auto it_next = std::next(myMap.begin(), 2);
std::cout << "Original map: ";
for (const auto& pair : myMap) {
std::cout << "{" << pair.first << ": " << pair.second << "} ";
}
std::cout << std::endl;
std::cout << "Iterator after std::next: {" << it_next->first << ": " << it_next->second << "}" << std::endl << std::endl;
// Example using std::advance
std::cout << "Example using std::advance:" << std::endl;
std::map<int, std::string> anotherMap = {{10, "ten"}, {20, "twenty"}, {30, "thirty"}};
auto it_advance = anotherMap.begin();
std::advance(it_advance, 2);
std::cout << "Original map: ";
for (const auto& pair : anotherMap) {
std::cout << "{" << pair.first << ": " << pair.second << "} ";
}
std::cout << std::endl;
std::cout << "Iterator after std::advance: {" << it_advance->first << ": " << it_advance->second << "}" << std::endl;
return 0;
}
Output:
Example using std::next:
Original map: {1: one} {2: two} {3: three}
Iterator after std::next: {3: three}
Example using std::advance:
Original map: {10: ten} {20: twenty} {30: thirty}
Iterator after std::advance: {30: thirty}
Example 3:
Let's take an example to illustrate the use of std::next() and std::advance() function in C++.
#include <iostream>
#include <deque>
#include <iterator>
int main() {
// Example using std::next
std::cout << "Example using std::next:" << std::endl;
std::deque<double> myDeque = {1.1, 2.2, 3.3, 4.4, 5.5};
auto it_next = std::next(myDeque.begin(), 3);
std::cout << "Original deque: ";
for (const auto& value : myDeque) {
std::cout << value << " ";
}
std::cout << std::endl;
std::cout << "Iterator after std::next: " << *it_next << std::endl << std::endl;
// Example using std::advance
std::cout << "Example using std::advance:" << std::endl;
std::deque<double> anotherDeque = {10.1, 20.2, 30.3, 40.4, 50.5};
auto it_advance = anotherDeque.begin();
std::advance(it_advance, 2);
std::cout << "Original deque: ";
for (const auto& value : anotherDeque) {
std::cout << value << " ";
}
std::cout << std::endl;
std::cout << "Iterator after std::advance: " << *it_advance << std::endl;
return 0;
}
Output:
Example using std::next:
Original deque: 1.1 2.2 3.3 4.4 5.5
Iterator after std::next: 4.4
Example using std::advance:
Original deque: 10.1 20.2 30.3 40.4 50.5
Iterator after std::advance: 30.3
Main Differences between std::next() and std::advance() in C++:
There are several differences between the std::next() and std::advance() function in C++. Some main differences between the std::next() and std::advance() are as follows:
S.No | Std::Next | Std::Advance |
1. | It is employed to return an iterator's nth successor. | It has no return type at all. |
2. | It requires an iterator and the number of elements as parameters. | Two parameters are required. quantity of components and iterator |
3. | In the best scenario, its time complexity is constant. | In the best scenario, its time complexity is constant. |
4. | In the worst scenario, its time complexity is linear. | In the worst scenario, its time complexity is linear. |
Conclusion:
In conclusion, two unique functions, std::next and std::advance, are provided by the C++ standard library and are intended to fulfil different functions when working with iterators. A useful function called std::next is mainly used to get a new iterator, which points to an element at a given position in relation to the original iterator without changing it. However, std::advance is a more versatile function designed to modify the original iterator in place by advancing it to a predetermined number of positions. Std::advance is used when it is desirable to modify the current iterator, whereas std::next is appropriate in situations where a new iterator is preferred. The selection between these functions is contingent upon the particular demands of the task; an appreciation of their differences leads to C++ code that is both more expressive and efficient.