std::exchange în C++

Pune o valoare nouă într-o variabilă și returnează valoarea veche.

Sintaxă
#include <utility>
template<class T, class U = T>
T exchange(T& obiect, U&& valoare_noua);

Ce face std::exchange

std::exchange(x, nou) face două lucruri într-un singur pas: îi dă lui x valoarea nou și returnează ce era înainte în x.

Este foarte folosit în constructorii de mutare: ptr(std::exchange(alt.ptr, nullptr)) preia pointerul celuilalt obiect și îl lasă pe acela gol, ca să nu elibereze de două ori aceeași resursă. Despre mutare, vezi și std::move.

Parametri

Parametru Descriere
obiect Variabila care primește valoarea nouă.
valoare_noua Valoarea pusă în obiect.

Ce returnează

Vechea valoare a lui obiect.

Exemple

Exemplul 1: Valoarea veche și cea nouă

#include <print>
#include <utility>

int main() {
    int stoc = 12;
    int vechi = std::exchange(stoc, 30);
    std::println("vechi = {}, acum = {}", vechi, stoc);
}

Rezultat

vechi = 12, acum = 30

Exemplul 2: Constructor de mutare

Obiectul nou preia bufferul, iar cel vechi rămâne cu nullptr și dimensiunea 0, deci destructorul lui nu mai șterge nimic.

#include <cstddef>
#include <print>
#include <utility>

class Buffer {
public:
    explicit Buffer(std::size_t n) : date_(new int[n]{}), n_(n) {}
    Buffer(Buffer&& alt) noexcept
        : date_(std::exchange(alt.date_, nullptr)), n_(std::exchange(alt.n_, 0)) {}
    ~Buffer() { delete[] date_; }
    std::size_t marime() const { return n_; }
private:
    int* date_;
    std::size_t n_;
};

int main() {
    Buffer a(100);
    Buffer b(std::move(a));
    std::println("a: {}, b: {}", a.marime(), b.marime());
}

Rezultat

a: 0, b: 100

Greșeli frecvente

  • Ignori valoarea returnată și folosești exchange ca pe o simplă atribuire. Merge, dar atunci x = nou; este mai clar.

Comenzi înrudite

  • std::swap: Schimbă între ele valorile a două variabile de același tip.
  • std::move: Mută elementele unui interval la o destinație, fără să le copieze (versiunea din <algorithm>).
  • std::forward: Transmite un argument mai departe păstrând felul lui: valoare temporară (mutabilă) sau variabilă cu nume.