[c++] std::exchange and std::exchange_if_not

In C++, std::exchange and std::exchange_if_not are utility functions provided by the standard library to simplify the process of value exchange. These functions are particularly useful in scenarios where you need to conditionally set a new value while simultaneously retrieving the old value. Let’s delve into the details of these utility functions.

std::exchange

The std::exchange function is defined as follows:

template <class T, class U = T>
T exchange(T& obj, U&& new_value);

Purpose

The purpose of std::exchange is to atomically store new_value into the object obj, and return the previous value of obj.

Parameters

Return Value

The previous value of obj.

Example

#include <iostream>
#include <utility>

int main() {
    int x = 1;
    int old_value = std::exchange(x, 10);
    std::cout << "Old value: " << old_value << std::endl;  // Output: Old value: 1
    std::cout << "New value: " << x << std::endl;          // Output: New value: 10
    return 0;
}

In the example above, std::exchange updates the value of x to 10 and returns the old value, which is 1.

std::exchange_if_not

The std::exchange_if_not function is a customization point that conditionally exchanges the value of the object, similar to std::exchange. However, it allows for a conditional exchange based on a provided predicate.

Purpose

The purpose of std::exchange_if_not is to conditionally store new_value into the object obj based on a provided predicate, and return the previous value of obj.

While std::exchange unconditionally swaps the values, std::exchange_if_not allows for an exchange only if a given predicate is true.

Parameters

Return Value

The previous value of obj.

Example

#include <iostream>
#include <utility>

bool should_exchange(int old_value, int new_value) {
    return new_value > old_value;
}

int main() {
    int x = 5;
    int old_value = std::exchange_if_not(x, 3, should_exchange);
    std::cout << "Old value: " << old_value << std::endl;  // Output: Old value: 5
    std::cout << "New value: " << x << std::endl;          // Output: New value: 5
    return 0;
}

In the example above, the exchange does not occur because the should_exchange predicate returns false.

Conclusion

std::exchange and std::exchange_if_not are powerful utilities for simplifying object value exchange, providing cleaner and more readable code. They promote code safety and clarity, making them valuable tools to have in your C++ toolkit.

References: