STL模板函数返回一对

时间:2017-09-15 19:51:11

标签: c++ algorithm c++11 templates std-pair

我正在尝试编写一个从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) ) {

我不知道如何处理。

除了那个错误,是否有更好的方法来实现所需的行为?

3 个答案:

答案 0 :(得分:4)

范围的

返回元素,而不是迭代器。所以你的循环应该是这样的:

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

答案 1 :(得分:2)

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为空。也许你应该添加一些检查它的检查。

答案 2 :(得分:1)

对于初学者,当容器为空时,该函数可能具有未定义的行为,因为可能会尝试取消引用空容器的迭代器。

像这样的循环

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

错误地使用了解除引用。

您可以使用标准算法std::minmax_element。但是它与您的代码不同。它返回第一个最小元素和最后一个最大元素。因此,您应该重写算法std::minmax_element,以便ir返回第一个最小元素(指向第一个最小元素的迭代器)和第一个最大元素(指向第一个最大元素的迭代器)。

可以通过以下方式定义函数

#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