std::next în C++

Iteratori C++11

std::next returnează un iterator mutat cu n poziții înainte, std::prev unul mutat înapoi; originalul rămâne neschimbat.

Sintaxă
template<class InputIt>
InputIt next(InputIt it, typename std::iterator_traits<InputIt>::difference_type n = 1);

template<class BidirIt>
BidirIt prev(BidirIt it, typename std::iterator_traits<BidirIt>::difference_type n = 1);

Ce face std::next

std::next(it) returnează iteratorul următorului element, iar std::next(it, n) pe cel aflat cu n poziții mai departe. std::prev(it, n) merge înapoi. Spre deosebire de std::advance, ele primesc o copie, deci iteratorul original nu se schimbă.

Sunt utile pentru containerele fără it + n (list, set, map): std::prev(m.end()) este ultimul element dintr-un map, std::next(l.begin(), 2) al treilea element dintr-o listă. std::prev cere iteratori bidirecționali, deci nu merge cu std::forward_list.

Parametri

Parametru Descriere
it Iteratorul de pornire (copiat).
n Numărul de poziții; implicit 1.

Ce returnează

Un iterator nou, mutat cu n poziții.

Exemple

Exemplul 1: Ultimul element dintr-un map și vecinii unui element

#include <iterator>
#include <list>
#include <map>
#include <print>
#include <string>

int main() {
    std::map<int, std::string> clasament{{1, "Ana"}, {2, "Ion"}, {3, "Maria"}};
    auto ultimul = std::prev(clasament.end());
    std::println("Ultimul loc: {} ({})", ultimul->first, ultimul->second);

    std::list<int> l{5, 10, 15, 20, 25};
    auto mijloc = std::next(l.begin(), 2);
    std::println("{} are vecinii {} și {}", *mijloc, *std::prev(mijloc), *std::next(mijloc));
}

Rezultat

Ultimul loc: 3 (Maria)
15 are vecinii 10 și 20

Exemplul 2: Compararea elementelor vecine

#include <iterator>
#include <print>
#include <set>

int main() {
    std::set<int> ore{8, 9, 12, 13, 14, 18};
    for (auto it = ore.begin(); std::next(it) != ore.end(); ++it) {
        if (*std::next(it) - *it > 1) {
            std::println("Pauză între {}:00 și {}:00", *it, *std::next(it));
        }
    }
}

Rezultat

Pauză între 9:00 și 12:00
Pauză între 14:00 și 18:00

Greșeli frecvente

  • Apelezi std::prev(c.end()) pe un container gol: rezultatul nu indică niciun element (comportament nedefinit). Verifică întâi !c.empty().
  • Folosești std::next(it, n) într-o buclă pe o listă mare, crescând n: fiecare apel parcurge din nou elementele, deci totul devine O(n²). Avansează același iterator pas cu pas.

Comenzi înrudite

  • std::advance: Mută un iterator cu n poziții înainte (sau înapoi, pentru n negativ), pentru orice tip de container.
  • std::distance: Numără câte poziții sunt între doi iteratori, adică câte elemente are intervalul [prim, ultim).
  • std::vector::begin: begin() dă un iterator la primul element, end() unul după ultimul, iar rbegin() pornește parcurgerea de la coadă.