вторник, 7 декабря 2010 г.

simple bind

В ряде алгоритмов стандартной библиотеки (например, find_if или remove_if) нужно писать функтор. Некоторые этот функтор пишут прямо рядом с вызовом функции, т.е. используют локальный класс (это разрешают некоторые компиляторы). Однако, стандарт запрещает использовать локальный класс в шаблонных функциях, а это значит, что неплохо бы ещё поместить этот функтор в отдельное пространство имен. Многовато кода для простого вызова функции...

Кстати, код будет выглядеть следующим образом:
#include <algorithm>
#include <vector>

struct some {
    long some_field1_;
    int some2_;
};

namespace impl {
// такая структура будет нужна для каждого поля, которое будет использоваться в алгоритмах
struct comp_some_some2 {
    comp_some_some2( int some2 ) : some2(some2) {}
    bool operator()( const some& x ) const { return (x.some2_==some2); }
private:
    int some2;
};
}//namespace impl

int main()
{
    std::vector<some> some_lot;
    // ...

    int to_find = 10;
    //
    std::find_if( 
      some_lot.begin(), 
      some_lot.end(), 
      impl::comp_some_some2(to_find) 
    );

    // ...    
    return 0;
}
Использование boost::bind сильно упрощает код, как можно видеть далее:
#include <algorithm>
#include <vector>
#include <boost/bind.hpp>
struct some {
    long some_field1_;
    int some2_;
};

int main()
{
    std::vector<some> some_lot;
    // ...

    int to_find = 10;
    // using boost::bind
    std::find_if( 
      some_lot.begin(), 
      some_lot.end(), 
      boost::bind(&some::some2_, _1) == to_find 
    );

    // ...
    return 0;
}
Для примера, приведу как это может выглядеть в C++0x:
// using C++ lambda function
std::find_if( 
  some_lot.begin(), 
  some_lot.end(), 
  [&to_find](const some& x){ return (x.some2_ == to_find); } 
);