Daily bit(e) C++. std::exchange

Добавлено 31 августа 2026 в 15:04

Daily bit(e) C++ 95, утилита из C++14 для обмена значениями в переменной: std::exchange.

Daily bit(e) C++

std::exchange в C++14 – это простая утилита, которая устанавливает первый аргумент в предоставленное значение и возвращает исходное значение.

Несмотря на свою простоту, такое поведение значительно упрощает типичную реализацию семантики перемещения и других вариантов использования, которые в противном случае должны были бы полагаться на временные переменные.

#include <utility>
#include <generator>
#include <iostream>

// std::exchange как вспомогательный инструмент для семантики перемещения
struct EraseOnMove 
{
    EraseOnMove(int value) : value_(value) {}
    EraseOnMove(EraseOnMove&& other) 
        : value_(std::exchange(other.value_, 0)) {}
    EraseOnMove& operator=(EraseOnMove&& other) 
    {
        // безопасно для this == &other
        value_ = std::exchange(other.value_, 0);
        /* Внимание: следующее небезопасно для this == &other
            value_ = std::move(other.value_);
            other.value_ = 0;
        */
        return *this;
    }
    int value_;
};

EraseOnMove a{10};
EraseOnMove b(std::move(a));
// a == {0}, b == {10}


// Последовательность Фибоначчи с использованием std::exchange
std::generator<int> fibonacci(size_t cnt) {
    int a = 0;
    int b = 1;
    while (cnt > 0) {
        co_yield std::exchange(a, std::exchange(b, a+b));
        /* то же самое, что и:
        int b_old = b;
        b = a + b;
        int a_old = a;
        a = b_old;
        co_yield a_old;
        */
        --cnt;
    }
}

// std::exchange как вспомогательный инструмент для разделения вывода
std::string delim = "";
for (int f : fibonacci(10))
    std::cout << std::exchange(delim,", ") << f;
std::cout << "\n";
// напечатает: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++Программирование