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';
а: 5, б: 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); }
if (a >= b) { std::swap(a, b); }
будет лучшим подходом здесь?