Каскадное использование связывателей (boost::bind) Mar 12, 2008

Никогда не обращал раньше внимания - начиная с версии boost 1.33, люди перегрузили !, ==, !=, <, <=, > и >=.

Возьмем рядовую задачу - дан массив точек, нужно удалить все точки с нулевыми координатами.

Лобовое решение:

struct Point { int x; int y; };
typedef std::vector PointsArray;

std::remove_if( PointsArray.begin(), PointsArray.end(), boost::bind( std::logical_and(),  boost::bind(std::equal_to(), boost::bind(&Point::x, _1), 0),  boost::bind(std::equal_to(), boost::bind(&Point::y, _1), 0) )));

Более понятная запись:

std::remove_if( PointsArray.begin(), PointsArray.end(), 
    boost::bind( boost::bind(&Point::x, _1) == 0 && boost::bind(&Point::y, _1) == 0)  ) );

Если опустить boost::, то получается совсем понятно… :-) А опустить boost:: таки можно, тут срабатывает Coenig lookup, поскольку _1 определяется так:

namespace
{
    boost::arg<1> _1;
} // unnamed namespace