2010-07-17 102 views
2

我是Boost新手,但沒有進行函數式編程,我試圖看看Boost能幫助我。如何使用Boost創建比較器?

我有一個2D點列表,我想提取最小的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))); 

是啊,這不漂亮:/
幸運的是,有可用的語法快捷方式,因爲函數對象通過的boost ::綁定產生過載了很多常用的操作,如<,所以你可以做:

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

但我認爲只有的C++ 0x的lambda真能實現簡潔清晰度:

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 2011-05-16 03:46:46