STL模板函数return一对

STL template function to return a pair

我正在尝试编写一个函数,returns 来自 STL 容器的一对值。

template <typename T>
std::pair<typename T::value_type,typename T::value_type> getMinMax(T &container) {

    auto min = *(container.begin());
    auto max = *(container.begin());

    for (auto it : container) {
        if (min > (*it) ) {
            min = (*it);
        }
        if (max < (*it) ) {
            max = (*it);
        }
    }
    return std::make_pair(min, max);
};

int main() {
    std::vector<int> c{1, 2, 3, 4, 5};
    auto p = getMinMax(c);
    std::cout << "min: " << p.first << " max: " << p.second << "\n";
}

我遇到一个错误:

error: indirection requires pointer operand ('int' invalid)
        if (min > (*it) ) {

我不知道怎么处理。

除了该错误之外,还有更好的方法来实现所需的行为吗?

for range returns 元素,不是迭代器。所以你的循环应该是这样的:

for (const auto& e : container) {
    if (min > e) {
        min = e;
    }
    if (max < e) {
        max = e;
    }
}

对于初学者来说,如果容器为空,函数可能有未定义的行为,因为可能会尝试取消引用空容器的迭代器。

像这样循环

for (auto it : container) {
    if (min > (*it) ) {
        min = (*it);
    }

解引用使用不当。

您可以使用标准算法 std::minmax_element。但是,它与您的代码不一样。它return是第一个最小元素和最后一个最大元素。所以你应该重写算法 std::minmax_element 这样 ir 会 return 第一个最小元素(迭代器指向第一个最小元素)和第一个最大元素(迭代器指向第一个最大元素).

函数可以这样定义,例如

#include <iostream>
#include <utility>
#include <vector>
#include <iterator>

template <typename T>
auto getMinMax( T &container ) 
    -> std::pair<decltype( container.begin() ), decltype( container.begin() )> 
{
    auto min = container.begin();
    auto max = container.begin();

    if ( !container.empty() )
    {
        for ( auto it = container.begin(); ++it != container.end();  )
        {
            if ( *it < *min ) min = it;
            else if ( *max < *it ) max = it;
        }
    }

    return { min, max };
}

int main() 
{
    std::vector<int> v = { 5, 2, 3, 7, 1, 4, 9, 8, 6 };

    auto minmax = getMinMax( v );

    std::cout << "Minimum = " << *minmax.first 
              << " at position " << std::distance( v.begin(), minmax.first )
              << " and maximum = " << *minmax.second
              << " at position " << std::distance( v.begin(), minmax.second )
              << std::endl;

    return 0;
}

程序输出为

Minimum = 1 at position 4 and maximum = 9 at position 6
template <typename T>
std::pair<typename T::value_type, typename T::value_type> getMinMax(T &container) {

    auto min = *(container.begin());
    auto max = *(container.begin());

    for (const auto& element : container) { /* ERROR WAS HERE, FOR RANGE LOOPS RETURN AN ELEMENT */
        if (min > element) {
            min = element;
        }
        if (max < element) {
            max = element;
        }
    }
    return std::make_pair(min, max);
};

嘿!这应该有效,您将 minmax 设置为取消引用的 element,这当然不是我们想要的。 :)

此外,您可能会得到未定义的行为,例如,如果 container 为空。也许你应该添加一些检查来检查它。