2015-09-23 8 views
8

私はstd::vector<int>あるfooを持っています。これは一連の範囲の「エッジ」値を表します。のstd :: bind2nd交換

たとえば、fooが{1,3,5,7,11}の場合、範囲は1〜3,5〜5,7〜7,11です。私のためには、これは4つの期間に相当します。各期間には範囲内の最初の数字が含まれ、最後の数字は含まれないことに注意してください。したがって、私の例では、8は3番目(ゼロベース)の期間に表示されます。 7は第3の期間にも現れる。 11以上はどこにも現れません。 2番目の期間に現れる。 intあるbar考える

は、私は私にbarを含まなければならない期間を与えること

std::find_if(
    foo.begin(), 
    foo.end(), 
    std::bind2nd(std::greater<int>(), bar) 
) - foo().begin() - 1; 

を使用しています。

私の問題:std::bind2ndは、私はリファクタリングするべきだので廃止されました。更新された関数を使用した同等のステートメントは何ですか? std::bindは明白な方法で「ドロップイン」しません。

あなたが std::bindを使用することができますC++ 11では
+3

ここで、std :: distance(foo.begin()、std :: lower_bound(foo.begin()、foo.end()、bar)) - 1; – Jarod42

答えて

9

、。ちょうどそれを使用する方法として明らかにされていません。

#include <functional> 
using namespace std::placeholders; 
std::find_if(
    foo.begin(), 
    foo.end(), 
    // create a unary function object that invokes greater<int>::operator() 
    // with the single parameter passed as the first argument and `bar` 
    // passed as the second argument 
    std::bind(std::greater<int>(), _1, bar) 
) - foo().begin() - 1; 

キーはstd::placeholders名前空間で宣言されているプレースホルダ引数の使用です。 std::bindは、それが呼び出されたときのパラメータのいくつかの数を取る関数オブジェクトを返します。 std::bindへの呼び出しで使用されるプレースホルダーは、結果のオブジェクトが呼び出されたときに提供される引数が、バインドしている呼び出し可能な呼び出し元への引数リストにどのようにマップされるかを示します。ですから、例えば:

auto op1 = std::bind(std::greater<int>(), _1, bar); 
op1(5); // equivalent to std::greater<int>()(5, bar) 

auto op2 = std::bind(std::greater<int>(), bar, _1); 
op2(5); // equivalent to std::greater<int>()(bar, 5) 

auto op3 = std::bind(std::greater<int>(), _2, _1); 
op3(5, bar); // equivalent to std::greater<int>()(bar, 5) 

auto op4 = std::bind(std::greater<int>(), _1, _2); 
op4(5, bar); // equivalent to std::greater<int>()(5, bar) 
5

bindバージョンは次のようになります。また奨励されている

[bar](const int a){return bar < a;} 

bind(std::greater<int>(), placeholders::_1, bar) 

が、私が思うに、のように、ラムダを使用する方が奨励されていますオーバーロードされた関数begin/endをメソッド呼び出しの代わりに使用します。何青銅器時代(bind)をバイパスして、C++ 14の一般的なラムダと鉄器時代へ(bind2nd)石器時代からまっすぐ行くことについて

find_if(begin(foo), end(foo), [bar](const int a){return bar < a;}) 
+0

'placeholders :: _ 1'とは何ですか? –

+0

あなたは天使も一緒に全部を入れてもらえますか? ;-) –

+0

@ P45文字通り_placeholders_; [here](http://www.cplusplus.com/reference/functional/placeholders/?kw=placeholders) –

8

:それは次のようになるでしょうか?

std::find_if(foo.begin(), foo.end(), [&](auto const& elem) { 
    return elem > bar; 
}); 

そして、入力がソートされている場合

std::lower_bound(foo.begin(), foo.end(), bar); 

は、ラムダがはるかに容易に読んでもstd::bind expresionsよりもインライン化が容易です。例えば、 Lavevej's CppCon 2015 talk。

+1

私はこれがおそらく最も簡単な解決策であることに同意しますが、質問のタグにはC++ 11のみが含まれています。 –

+0

@JasonR私の哲学は、C++ 14を本当に使用できないと主張していない限り、どのようにコード化するのかを示すことであり、節約が十分であればそれを示しています。Q&Aは単なるOPのためにではなく、大衆のために。しかし私はあなたの 'バインド'答えをupvoted: – TemplateRex

+0

十分な公正;それは理にかなっている。 +1。 –