2017-09-15 72 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如果容器是空的,則呈現的函數具有未定義的行爲。:) –