Адаптеры отрицатели в STL - PullRequest
1 голос
/ 02 июня 2009

Рассмотрим следующий пример:

#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 ]

3 голосов
/ 02 июня 2009

Поскольку вы используете Boost.Bind:

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

(обратите внимание на "!")

2 голосов
/ 02 июня 2009

Если вы используете унарные функторы (в смысле 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() ) );
}

Но это не работает с unspecified_type , который возвращается из boost :: bind. Для этого вы можете использовать, как уже писал Эрик,! оператор над unspecified_type возвращено.

2 голосов
/ 02 июня 2009

Аргумент std::not2 должен выглядеть как «нормальный» двоичный предикат, поэтому вам нужно адаптировать foo::is_equal к чему-то вроде std::mem_fun_ref. Вы должны быть в состоянии сделать что-то вроде:

std::not2(std::mem_fun_ref(&foo::is_equal))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...