c++c++11tuplesstd-pairminmax

Is there a way to easily handle functions returning std::pairs?


C++11 has function std::minmax_element which returns a pair of values. This, however, is quite confusing to handle and read, and produces an extra, later useless variable to pollute the scope.

auto lhsMinmax = std::minmax_element(lhs.begin(), lhs.end());
int &lhsMin = *(lhsMinMax.first);
int &lhsMax = *(lhsMinmax.second);

Is there a better way to do this? Something like:

int lhsMin;
int lhsMax;
std::make_pair<int&, int&>(lhsMin, lhsMax).swap(
    std::minmax_element(lhs.begin(), lhs.end()));

Solution

  • This looks like enough of a common case to prompt a helper function:

    template <class T, std::size_t...Idx>
    auto deref_impl(T &&tuple, std::index_sequence<Idx...>) {
        return std::tuple<decltype(*std::get<Idx>(std::forward<T>(tuple)))...>(*std::get<Idx>(std::forward<T>(tuple))...);
    }
    
    template <class T>
    auto deref(T &&tuple)
        -> decltype(deref_impl(std::forward<T>(tuple), std::make_index_sequence<std::tuple_size<std::remove_reference_t<T>>::value>{})) {
        return deref_impl(std::forward<T>(tuple), std::make_index_sequence<std::tuple_size<std::remove_reference_t<T>>::value>{});
    }
    
    // ...
    
    int lhsMin;
    int lhsMax;
    std::tie(lhsMin,lhsMax) = deref(std::minmax_element(lhs.begin(), lhs.end()));
    

    index_sequence is C++14, but a full implementation can be made in C++11.

    Note: I'd keep the repeated decltype in deref's return type even in C++14, so that SFINAE can apply.

    See it live on Coliru