2010-07-17 2 views
2

Я новичок в Boost, но не в функциональном программировании, и я пытаюсь понять, где Boost может мне помочь.Как создать компаратор с Boost?

У меня есть список двумерных точек, и я хочу извлечь минимальную координату x. Point класс имеет функцию члена float x() const так что я могу использовать boost::mem_fn следующим образом:

boost::mem_fn(&Point::x) 

Но для того, чтобы использовать std::min_element, мне нужен объект, который поддерживает bool operator()(Point const &, Point const &). Что-то вроде этого вымышленного compare_by:

leftmostPoint = std::min_element(
    points.begin(), points.end(), 
    boost::compare_by(boost::mem_fn(&Point::x))); 

Могу ли я использовать подталкивание построить такое сравнение, или же мне нужно сделать это сам?


Обновление: Вот моя собственная реализация, но мне все же интересно узнать, как Boost мог это сделать для меня.

template<typename F> 
class CompareBy { 
    F const d_f; 
    public: 
     CompareBy(F f) : d_f(f) { } 
     template<typename T> 
     bool operator()(T const &a, T const &b) const { 
      return d_f(a) < d_f(b); 
     } 
}; 

template<typename F> 
CompareBy<F> compare_by(F f) { 
    return CompareBy<F>(f); 
} 

Использование: как указано выше, за вычетом boost:: пространства имен.

ответ

4

Я не знаю никакой конструкции форсирования, похожей на ваш Compare_by.
Однако boost :: bind может сделать трюк.

Point leftmostPoint = *std::min_element(points.begin(), points.end(), 
    boost::bind(std::less<Point::type_x>(), 
     boost::bind(&Point::x, _1), boost::bind(&Point::x, _2))); 

Да, это не очень:/
К счастью, есть синтаксис ярлык доступен, так как функциональные объекты производства повышающего :: затруднительных перегружать много обычного оператор, как <, так что вы можете сделать:

Point leftmostPoint2 = *std::min_element(points.begin(), points.end(), 
boost::bind(&Point::x, _1) < boost::bind(&Point::x, _2)); 

Но я думаю, что лямбда только C++ 0x может реально достичь краткости и ясности:

Point leftmostPoint3 = *std::min_element(points.begin(), points.end(), 
[](const Point& p1, const Point& p2){ return p1.x < p2.x; }); 
+0

Я думаю, что lamba нужен тип логического возврата, т. Е. '[] (Const Point & p1, const Point & p2) -> bool'. – mavam

Смежные вопросы