std::ref în C++

Împachetează o referință ca să poată fi transmisă prin funcții care copiază argumentele (thread, bind).

Sintaxă
#include <functional>
template<class T> std::reference_wrapper<T> ref(T& t) noexcept;
template<class T> std::reference_wrapper<const T> cref(const T& t) noexcept;

Ce face std::ref

Unele funcții copiază mereu argumentele: std::thread, std::bind, std::make_pair. Dacă vrei ca ele să lucreze cu variabila originală, nu cu o copie, o împachetezi cu std::ref(x). Pentru acces doar la citire, std::cref(x).

Rezultatul este un std::reference_wrapper: un obiect mic, copiabil, care se comportă ca o referință. Poate fi pus și într-un container (std::vector<std::reference_wrapper<T>>), unde referințele obișnuite nu sunt permise.

Parametri

Parametru Descriere
t Variabila la care vrei o referință.

Ce returnează

Un std::reference_wrapper<T> (sau <const T> pentru cref).

Exemple

Exemplul 1: Cu și fără std::ref într-un fir de execuție

std::thread copiază argumentele. Fără std::ref, funcția ar modifica o copie (de fapt, nici nu ar compila, pentru că parametrul este int&).

#include <functional>
#include <print>
#include <thread>

void adaugaPuncte(int& scor, int puncte) { scor += puncte; }

int main() {
    int scor = 10;
    std::thread t(adaugaPuncte, std::ref(scor), 5);
    t.join();
    std::println("scor: {}", scor);
}

Rezultat

scor: 15

Exemplul 2: bind cu std::cref și un vector de referințe

#include <functional>
#include <print>
#include <string>
#include <vector>

void salut(const std::string& nume) { std::println("Salut, {}!", nume); }

int main() {
    std::string nume = "Ana";
    auto f = std::bind(salut, std::cref(nume));
    nume = "Ioana";
    f();   // vede valoarea actuală, nu o copie

    int a = 1, b = 2;
    std::vector<std::reference_wrapper<int>> v{a, b};
    for (int& x : v) x *= 10;
    std::println("a = {}, b = {}", a, b);
}

Rezultat

Salut, Ioana!
a = 10, b = 20

Greșeli frecvente

  • Trimiți std::ref la o variabilă locală unui fir de execuție detașat sau unei funcții care se apelează mai târziu. Dacă variabila este distrusă înainte, referința devine invalidă.

Comenzi înrudite

  • std::thread: Pornește o funcție pe un fir de execuție separat, care rulează în paralel cu restul programului.
  • std::bind: Creează o funcție nouă dintr-una existentă, fixând unele argumente sau schimbându-le ordinea.
  • referințe (&, &&): O referință este un alt nume pentru o variabilă existentă; tot ce faci cu referința se face de fapt cu variabila originală.
  • std::function: Variabilă care poate ține orice funcție, lambda sau obiect apelabil cu o anumită semnătură.