std::initializer_list în C++

Tipul listei scrise între acolade, {1, 2, 3}: permite funcțiilor și claselor să primească oricâte valori de același tip.

Sintaxă
#include <initializer_list>

void functie(std::initializer_list<T> lista);
Clasa(std::initializer_list<T> lista);

Ce face std::initializer_list

Când scrii std::vector<int> v{1, 2, 3};, acoladele creează un std::initializer_list<int>, iar vectorul are un constructor care îl primește. Poți face la fel în funcțiile și clasele tale: un parametru std::initializer_list<T> acceptă orice listă {a, b, c} cu elemente de tipul T.

Lista are size(), begin(), end() și se parcurge cu for. Elementele sunt constante (nu le poți modifica sau muta). Dacă o clasă are un constructor cu initializer_list, acoladele îl preferă pe acesta: de aici diferența dintre std::vector<int>{5} (un element) și std::vector<int>(5) (cinci elemente).

Parametri

Parametru Descriere
T Tipul comun al elementelor din listă.

Ce returnează

O vedere constantă asupra elementelor listei.

Exemple

Exemplul 1: Funcție cu oricâte argumente

#include <initializer_list>
#include <print>

int suma(std::initializer_list<int> numere) {
    int total = 0;
    for (int n : numere) {
        total += n;
    }
    return total;
}

int main() {
    std::println("{}", suma({1, 2, 3}));
    std::println("{}", suma({10, 20, 30, 40, 50}));
    std::println("{}", suma({}));
}

Rezultat

6
150
0

Exemplul 2: Constructor cu listă și diferența {} față de ()

#include <initializer_list>
#include <print>
#include <string>
#include <vector>

class Playlist {
public:
    Playlist(std::initializer_list<std::string> melodii) : melodii_(melodii) {}
    std::size_t numar() const { return melodii_.size(); }
private:
    std::vector<std::string> melodii_;
};

int main() {
    Playlist p{"Ciocârlia", "Hora Unirii", "Perinița"};
    std::println("Playlist cu {} melodii", p.numar());

    std::vector<int> a{5};       // initializer_list: un element, 5
    std::vector<int> b(5);       // constructor cu dimensiune: cinci zerouri
    std::println("a = {}, b = {}", a, b);
}

Rezultat

Playlist cu 3 melodii
a = [5], b = [0, 0, 0, 0, 0]

Greșeli frecvente

  • Păstrezi un std::initializer_list ca membru al unei clase sau îl returnezi dintr-o funcție. Elementele listei temporare dispar la sfârșitul expresiei; copiază-le într-un std::vector.
  • Încerci să muți elementele dintr-o listă (std::move(*it)): sunt constante, deci se copiază oricum. De aceea obiectele care nu se pot copia nu pot fi scoase din listă: std::vector<std::unique_ptr<int>> v{std::make_unique<int>(1)}; nu compilează; folosește push_back sau emplace_back.

Comenzi înrudite

  • std::vector: Tabloul dinamic din C++: ține elementele unul după altul în memorie și își mărește singur dimensiunea.
  • std::array: Tablou cu dimensiune fixă, cunoscută la compilare, cu interfața unui container (size, at, begin, end).
  • std::tuple: Grupează oricâte valori de tipuri diferite într-un singur obiect; generalizarea lui std::pair.