std::ranges::to în C++

Transformă un range sau un view (filtrat, transformat) într-un container nou: vector, set, string, map.

Sintaxă
auto c = range | std::ranges::to<Container>();
auto c = std::ranges::to<Container>(range);

Ce face std::ranges::to

View-urile (std::views::filter, transform etc.) nu stochează nimic: calculează elementele când le parcurgi. Când vrei rezultatul salvat, std::ranges::to (C++23) construiește un container din ele.

Poți scrie tipul complet (std::ranges::to<std::vector<int>>()) sau doar șablonul (std::ranges::to<std::vector>()), iar tipul elementelor este dedus. Merge cu orice container: std::set (elimină dublurile și sortează), std::string, std::map (din perechi).

Parametri

Parametru Descriere
Container Tipul containerului rezultat, complet sau doar numele șablonului.
range Sursa: un view sau alt container.

Ce returnează

Un container nou cu elementele range-ului.

Exemple

Exemplul 1: Filtrare și transformare salvate într-un vector

Prețurile de cel puțin 40 de lei primesc 10% reducere. Împărțirea între întregi taie zecimalele: 85 devine 76, nu 76,5.

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

int main() {
    std::vector<int> preturi{12, 85, 40, 150, 9, 300};

    auto reduse = preturi
                | std::views::filter([](int p) { return p >= 40; })
                | std::views::transform([](int p) { return p * 9 / 10; })
                | std::ranges::to<std::vector>();

    std::println("{}", reduse);
}

Rezultat

[76, 36, 135, 270]

Exemplul 2: Spre set, string și map

#include <cctype>
#include <map>
#include <print>
#include <ranges>
#include <set>
#include <string>
#include <vector>

int main() {
    std::vector<int> v{4, 1, 4, 3, 1};
    auto unice = v | std::ranges::to<std::set>();
    std::println("Set: {}", unice);

    std::string text = "A n a - M a r i a";
    auto fara_spatii = text | std::views::filter([](char c) { return c != ' '; }) | std::ranges::to<std::string>();
    std::println("Text: {}", fara_spatii);

    std::vector<std::string> nume{"Ana", "Ion", "Elena"};
    auto lungimi = nume | std::views::transform([](const std::string& n) { return std::pair{n, n.size()}; })
                 | std::ranges::to<std::map>();
    std::println("Map: {}", lungimi);
}

Rezultat

Set: {1, 3, 4}
Text: Ana-Maria
Map: {"Ana": 3, "Elena": 5, "Ion": 3}

Greșeli frecvente

  • Folosești std::ranges::to cu un compilator setat pe C++20: funcția există doar din C++23.
  • Păstrezi un view peste un container care este distrus între timp. Dacă rezultatul trebuie să trăiască mai mult, salvează-l cu ranges::to.

Comenzi înrudite

  • std::views::filter: Creează o vedere asupra unui container care conține doar elementele ce îndeplinesc o condiție, fără copiere.
  • std::views::transform: Creează o vedere în care fiecare element este rezultatul unei funcții aplicate elementului original.
  • std::views::split: Împarte un range (de obicei un text) în bucăți, după un separator: un caracter sau o secvență.
  • std::copy: Copiază elementele unui interval (copy) sau primele n elemente (copy_n) la o destinație.