2017-09-15 6 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:container){ if(min>( * it)){ min =(* 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 :: map :: insert()'と同様の) 'bool'が成功/失敗を示している' std :: pair 'を代わりに返すかもしれませんか?それ以外の場合は、代わりに例外をスローします。 –

+0

私はこれを知らなかった。ありがとうございました –

+0

@Remy Lebeauコンテナが空の場合、表示された関数の動作は未定義です:) –

関連する問題