2017-04-04 14 views
4

は両方std::lower_bound & std::upper_boundのためのサンプル例であり、それらに渡されるラムダ比較のサインに気づく -異なる比較署名:: LOWER_BOUNDここ

const auto lower_x = std::lower_bound(
      points.begin(), points.end(), rec.min_corner.x, 

      [](const RankedPoint &rp, const double x) { return rp.point.x < x; }); 

const auto upper_x = std::upper_bound(
      points.begin(), points.end(), rec.max_corner.x, 

      [](const double x, const RankedPoint &rp) { return x < rp.point.x; }); 

を可能推論とは何ですか署名を互いに正確に反対にすることの背後にあるか?私はこのことを認識しておらず、間違った署名を持つ明確な型の代わりにautoを使用したときにgccをコンパイルしました(clangはしませんでした)。 10分の欲求不満を払った。

+0

比較関数の意味は "<"より小さい必要があるためです。 – kennytm

+0

範囲ライブラリによってこの問題が解決されます:-) – Jarod42

答えて

3

カスタムコンパレータのバージョンlower_boundupper_boundは、単に<を使用する一般化です。 lower_boundvalue以上の最初の要素を生成するので、発生するチェックはelem < value(または!(elem < value))です。 upper_boundは、最初の要素がより多く、よりもvalueですが、elem > value(これはoperator>が必要です)を書く代わりに、value < elemに並べ替えます。これにより、唯一の要件がoperator<に維持されますが、結果として引数の順序が逆になります。

これは一般的に、elem < valueからcomp(elem, value)およびvalue < elemからcomp(value, elem)になります。

最終的には、これを設計するときに2つの選択肢があります:の同じコンパレータをどこでも使用できますが、いくつかのアルゴリズムでは引数の順序が逆になります。あるいは、特定のアルゴリズムに意味があるかどうかによって、アルゴリズムごとにの異なるコンパレータを使用できます。どこでも同じコンパレータを使用すると、多くの利点を持っている - あなただけの同じコンパレータを使用します。どこでも

std::vector<int> vs = ...; 
std::sort(vs.begin(), vs.end(), std::greater<>{}); 
auto lo = std::lower_bound(vs.begin(), vs.end(), 5, std::greater<>{}); 
auto hi = std::upper_bound(vs.begin(), vs.end(), 5, std::greater<>{}); 

同じコンパレータを、コードが正しく見え、正しいことを行います。 upper_bound()がコンパレータに渡す引数の順序を反転した場合、std::less<>{}に渡す必要があります。どちらかというと...間違って見える。


は、あなたはおそらく、呼び出し可能な突起がこの問題を解決Ranges TS、に興味があるでしょう。

+0

独自の投影法を書くことはすべてテンプレート '' 012 '' '' ' > bool {return f(lhs) Yakk

関連する問題