std::tie(a, b) = std::minmax(a, b);
Я думаю, что это интуитивно понятный код.Чисто и понятно.Жаль, что он не работает как задумано, как std::minmax
шаблоны для const&
.Следовательно, если значения поменялись местами внутри std::pair<const&, const&>
, то одно назначение перезапишет другое значение:
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
Ожидаемоевывод здесь a: 5, b: 7
.
Я думаю, что это важно, поскольку реализация функций преобразования для применения функции к некоторым диапазонам требует таких выражений для интуитивно понятных лямбд.Например:
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}
Одно решение, которое я нашел, заключалось в явном создании std::tuple
без каких-либо ссылочных квалификаторов над std::pair<const&, const&>
для принудительного применения копии:
std::tie(a, b) = std::tuple<int, int>(std::minmax(a, b));
Но эта <int, int>
избыточность кажется довольно ужасной, особенно если сказать auto& a, auto& b
раньше.
Есть ли хороший, короткий способ выполнить это задание?Может быть, это неправильное направление, и просто сказать, что if (a >= b) { std::swap(a, b); }
будет лучшим подходом здесь?