среда, 3 декабря 2008 г.

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

Никогда не обращал раньше внимания - начиная с версии 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

Комментариев нет: