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
exchangeca pe o simplă atribuire. Merge, dar atuncix = 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.