std::tie(a, b) = std::minmax(a, b);
I think this is intuitive code. Clean and understandable. Too bad it doesn't work as intended, as std::minmax
templates for const&
. If therefore the values are swapped inside the std::pair<const&, const&>
than one assignement will overwrite the other value:
auto[a, b] = std::make_pair(7, 5);
std::tie(a, b) = std::minmax(a, b);
std::cout << "a: " << a << ", b: " << b << '\n';
a: 5, b: 5
The expected output here is a: 5, b: 7
.
I think this is important as implementing transform functions to apply a function onto some ranges requires such statements for intuitive lambdas. For example:
std::vector<int> v{ 0, 1, 0, 2, 0 };
std::vector<int> u{ 1, 0, 1, 0, 1 };
perform(v.begin(), v.end(), u.begin(), [](auto& a, auto& b){
std::tie(a, b) = std::minmax(a, b);
});
//v would be == {0, 0, 0, 0, 0}
//u would be == {1, 1, 1, 2, 1}
One solution I found was constructing an std::tuple
explicitly without any reference qualifiers over the std::pair<const&, const&>
to enforce a copy:
std::tie(a, b) = std::tuple<int, int>(std::minmax(a, b));
But this <int, int>
redundancy seems rather awful, especially when having saidauto& a, auto& b
before.
Is there a nice, short way to perform this assignement? Could it be that this is the wrong direction and just saying if (a >= b) { std::swap(a, b); }
would be the best approach here?