std::views::zip în C++

Parcurge mai multe range-uri în paralel, oferind la fiecare pas un tuplu cu elementele de pe aceeași poziție.

Sintaxă
auto v = std::views::zip(range1, range2, ...);

Ce face std::views::zip

std::views::zip (C++23) leagă două sau mai multe containere: la pasul i primești (a[i], b[i], ...). Cu structured bindings scrii for (auto [nume, nota] : std::views::zip(nume, note)).

Lungimea rezultatului este cea a celui mai scurt range. Elementele din tuplu sunt referințe, deci prin ele poți modifica containerele originale.

Parametri

Parametru Descriere
range1, range2, ... Range-urile parcurse împreună.

Ce returnează

Un view de tupluri.

Exemple

Exemplul 1: Nume și note

#include <print>
#include <ranges>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> elevi{"Ana", "Ion", "Maria"};
    std::vector<double> note{9.5, 7.0, 8.75};

    for (auto [elev, nota] : std::views::zip(elevi, note)) {
        std::println("{:<6} {:.2f}", elev, nota);
    }
}

Rezultat

Ana    9.50
Ion    7.00
Maria  8.75

Exemplul 2: Modificare prin zip și lungimi diferite

Variabila pret este o referință în vectorul preturi. Al treilea preț nu are reducere pereche, deci este ignorat.

#include <print>
#include <ranges>
#include <vector>

int main() {
    std::vector<int> preturi{100, 250, 80};
    std::vector<int> reduceri{10, 50};

    for (auto [pret, reducere] : std::views::zip(preturi, reduceri)) {
        pret -= reducere;
    }
    std::println("{}", preturi);
    std::println("Perechi: {}", std::views::zip(preturi, reduceri).size());
}

Rezultat

[90, 200, 80]
Perechi: 2

Greșeli frecvente

  • Te aștepți ca zip să semnaleze vectori de lungimi diferite. Se oprește în tăcere la cel mai scurt.
  • Scrii for (auto& [a, b] : std::views::zip(...)): nu compilează, pentru că tuplurile sunt valori temporare. Folosește auto sau auto&&; elementele sunt oricum referințe.

Comenzi înrudite

  • std::views::transform: Creează o vedere în care fiecare element este rezultatul unei funcții aplicate elementului original.
  • std::views::iota: Generează numerele consecutive dintr-un interval (sau la infinit) fără să le stocheze.
  • std::views::keys: Din perechi (de exemplu dintr-un std::map), păstrează doar cheile (keys) sau doar valorile (values).