2015-11-04 58 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))); 
}