Swapping values in C++ is simple enough with the
std::swap standard algorithm. But what if an operation logically requires some transformation on one or both values prior to swapping? Is there some idiomatic solution to combining a swap with transformations? Here’s a quick tip to show how to achieve this goal with a little inspiration from other languages.
The Standard Approach
Given two variables of the same type, swapping and then performing some transforming operation like negating one of the values looks like the following:
int x = 1, y = 9; std::swap(x, y); x=-x;
Simple and efficient enough. But does it really capture the intention in a way that can be understood by the reader?
For example, what if the specific logical goal was to take a 2D vector and create a new one by swapping the x and negated-y coordinates? Negating the
x after swapping certainly achieves the desired final value, but logically the negation is of the
y value and this information becomes lost in this standard approach.
Negating the y-value before swapping achieves the goal while also retaining the logical reasoning behind the operation, albeit with a two-step process.
int x = 1, y = 9; y=-y; std::swap(x, y);
There is nothing wrong with this solution, however, wouldn’t it be nice to write something a little more expressive like the following?
int x = 1, y = 9; std::swap(x, -y);
Of course, this blows up spectacularly in C++ compiler fashion because the swap algorithm expects l-value’s for its arguments. But is there some other way to achieve this goal?
Insight From Other Languages
While recently needing to do this exact operation of negating while swapping I remembered seeing a similar trick in the past using python’s tuple type.
>>> x=1 >>> y=9 >>> (x,y)=(-y,x) >>> x -9
The expressiveness of this trick in python is what made it stick with me. But wait. Doesn’t C++ have a tuple type? Why yes, yes it does.
Tuple/Tie to Swap
C++ provides a tuple type and a tie helper to unpack values. Using the python example as guidance, the C++ solution looks like the following.
int x = 1, y = 9; std::tie(x, y) = std::make_tuple(-y, x);
Not as terse as the python solution, but still expressive and when compiled with optimizations results in the same generated bytecode as the swap solution.
It pays to spend time with other programming languages enough to learn their idioms. The problem solving tools gained can amp up the quality of code written across the board.