2015-11-04 77 views
1

我想使用binary_functioncompose2在C + + 11與std::bind而不使用boost庫。如何使用std :: bind與compose2?

編輯:或labmdas。

假設我有以下定義:

bool GreaterThanFive(int x) { return x > 5; } 

struct DivisibleByN : binary_function<int, int, bool> { 
    bool operator()(int x, int n) const { return x % n == 0; } 
}; 

說我要算其中大於5和被3整除一個向量的元素,我可以很容易地用下面結合他們:

int NumBothCriteria(std::vector<int> v) { 
    return std::count_if(v.begin(), v.end(), 
         __gnu_cxx::compose2(std::logical_and<bool>(), 
              std::bind2nd(DivisibleByN(), 3), 
              std::ref(GreaterThanFive))); 
} 

由於bind2nd從C++ 11開始已棄用,我想轉移到std::bind。我還沒有弄清楚爲什麼以下不等價(並且不能編譯)。

int NumBothCriteria(std::vector<int> v) { 
    using namespace std::placeholders; 
    return std::count_if(v.begin(), v.end(), 
         __gnu_cxx::compose2(std::logical_and<bool>(), 
              std::bind(DivisibleByN(), _1, 3), 
              std::ref(GreaterThanFive))); 
} 

它給了我下面的編譯錯誤:

no type named 'argument_type' in 'std::_Bind<DivisibleByN *(std::_Placeholder<1>, int)>` 
    operator()(const typename _Operation2::argument_type& __x) const 
        ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~ 

我的直覺是,std::bind沒有做的事情做std::bind2nd,但我不知道如何讓argument_type的typedef回來。

My search came up with three questions.第一次使用bind2nd,第二次使用boost,第三次使用C++ 03。不幸的是有效的STL仍然使用std::bind2nd

+2

不'的std :: bind'支撐組分自身,所以如果你用'的std :: bind'取代'__gnu_cxx :: compose2'這應該工作? –

+0

@PiotrSkotnicki是的,你可以。不知道爲什麼我最初回復你說你不能。 – Barry

回答

2

只是不要使用bindcompose2。以後你會感謝自己:

int NumBothCriteria(std::vector<int> v) { 
    return std::count_if(v.begin(), v.end(), 
         [](int i){ return i > 5 && i%3 == 0; }); 
} 

你要找的答案是,你可以簡單地替代使用std::bind你使用__gnu_cxx::compose2其中:

return std::count_if(v.begin(), v.end(), 
    std::bind(std::logical_and<bool>(), 
     std::bind(DivisibleByN(), _1, 3), 
     std::bind(GreaterThanFive, _1))); 

但是,這是比使用lambda更加複雜和難以推理。

+0

我上面的例子與我實際做的很相似。 –

+0

@ WillBeason嗯,我確定你實際上在做什麼也會從使用lambda得到好處。 – Barry

+3

我明白如何用lambdas做到這一點。這個問題的關鍵是要學習如何在這種情況下使用'std :: bind'。 –

0

我想出瞭如何使它與std::function一起使用。

int NumBothCriteria2(std::vector<int> v) { 
    using std::placeholders::_1; 
    return std::count_if(v.begin(), v.end(), 
         __gnu_cxx::compose2(std::logical_and<bool>(), 
              std::function<int(int)>(std::bind(
               DivisibleByN(), _1, 3)), 
              std::ref(GreaterThanFive))); 
}