2017-09-15 73 views
-1

我想写一个从STL容器返回一对值的函数。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)) { 

我不知道该如何面对这一切。

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

+2

http://en.cppreference.com/w/cpp/algorithm/minmax – Justin

+4

*是否有更好的方法来实现所需的行为?*。是的,['std :: minmax_element'](http://en.cppreference.com/w/cpp/algorithm/minmax_element) – NathanOliver

+3

@ user1211030在这个代码片段中用于(auto it:容器){if(min>( * it)){分钟=(* it); }它不是一个迭代器或指针。它具有值类型。所以删除解引用。 –

回答

4

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

for (const auto& e : container) { 
    if (min > e) { 
     min = e; 
    } 
    if (max < e) { 
     max = e; 
    } 
} 
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 
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是空的。也许你应该添加一些检查来检查。

+1

'std :: pair'必须有值,它不能为空。如果容器是空的,返回一个默认的'std :: pair'将包含可能混淆调用者的值,如果他们真的不是这样的值。也许返回'std :: pair '而不是'bool'指示成功/失败(类似于'std :: map :: insert()')?否则,只需抛出一个异常。 –

+0

我不知道这个。谢谢 –

+0

@Remy Lebeau如果容器是空的,则呈现的函数具有未定义的行为。:) –