代码之家  ›  专栏  ›  技术社区  ›  Thomas

如何用boost创建一个比较器?

  •  2
  • Thomas  · 技术社区  · 15 年前

    我对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来构建这样一个比较吗,还是我需要自己来做?


    更新:这是我自己的实现,但我仍然有兴趣看看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:: 命名空间。

    1 回复  |  直到 15 年前
        1
  •  4
  •   Arzar    15 年前

    我不知道有任何类似于你比较的增强结构。
    但是,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::bind生成的函数对象重载了许多常见的运算符,如<,所以您可以这样做:

    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; });