STL中的否定适配器

时间:2009-06-02 13:40:52

标签: c++ boost

请考虑以下示例:

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>

#include <boost/bind.hpp>

const int num = 3;

class foo {
private:
    int x;
public:
    foo(): x(0) {}
    foo(int xx): x(xx) {}
    ~foo() {}
    bool is_equal(int xx) const {
        return (x == xx);
    }
    void print() {
        std::cout << "x = " << x << std::endl;
    }
};

typedef std::vector<foo> foo_vect;

int
main() {
    foo_vect fvect;
    for (int i = -num; i < num; i++) {
        fvect.push_back(foo(i));
    }
    foo_vect::iterator found;
    found = std::find_if(fvect.begin(), fvect.end(),
        boost::bind(&foo::is_equal, _1, 0));
    if (found != fvect.end()) {
        found->print();
    }
    return 0;
}

有没有办法使用某种带foo::is_equal()的否定适配器来找到第一个非零元素。我不想写foo::is_not_equal(int)方法,我相信有更好的方法。我尝试使用std::not2,但没有成功。

3 个答案:

答案 0 :(得分:3)

因为你正在使用Boost.Bind:

std::find_if(fvect.begin(), fvect.end(),
    !boost::bind(&foo::is_equal, _1, 0)
);

(注意“!”)

答案 1 :(得分:2)

std::not2的参数需要看起来像'正常'二元谓词,因此您需要使用foo::is_equal来调整std::mem_fun_ref。您应该可以执行以下操作:

std::not2(std::mem_fun_ref(&foo::is_equal))

答案 2 :(得分:2)

如果你正在使用一元仿函数(在STL意义上)你可以使用std :: not1:

struct odd : public std::unary_function<int,bool>
{
   bool operator()( int data ) const {
      return data % 2;
   }
};
void f( std::vector<int> const & v )
{
   std::vector<int>::const_iterator first_odd
        = std::find_if( v.begin(), v.end(), odd() );
   std::vector<int>::const_iterator first_even 
        = std::find_if( v.begin(), v.end(), std::not1( odd() ) );
}

但是这不适用于从boost :: bind返回的 unspecified_type 。为此你可以使用,正如Éric已发布的那样! unspecified_type 返回的运算符。