【问题标题】:How can I use Boost.Bind on compound types?如何在复合类型上使用 Boost.Bind?
【发布时间】:2011-01-25 15:43:54
【问题描述】:

我有std::map<int, std::pair<short, float> >,我需要在这张地图中找到最小的short。为此,我如何使用boost::bindstd::min_element()

boost::lambda?

【问题讨论】:

    标签: c++ boost-bind boost-lambda


    【解决方案1】:

    map 迭代器会给你一个pair,其中firstint 键,second 是映射的pair 值,所以如果你有一个迭代器it,你会想要所有it->second.first 值中的最小值。 min_element 函数需要一个比较函数作为其第三个参数,因此您需要构建一个比较函数来投影其两个参数的 second.first

    我们将从一些 typedef 开始,以使代码更具可读性:

    typedef std::pair<short, float> val_type;
    typedef std::map<int, val_type> map_type;
    map_type m;
    

    我们将使用 Boost.Lambda 作为其重载运算符,允许我们使用operator&lt;。 Boost.Bind 可以绑定成员变量和成员函数,所以我们也会利用这一点。

    #include <boost/bind.hpp>
    #include <boost/lambda/lambda.hpp>
    using boost::bind;
    
    // Comparison is (_1.second.first < _2.second.first)
    std::cout <<
      std::min_element(m.begin(), m.end(),
        bind(&val_type::first, bind(&map_type::iterator::value_type::second, _1))
        <
        bind(&val_type::first, bind(&map_type::iterator::value_type::second, _2))
      )->second.first;
    

    这也适用于boost::lambda::bind

    【讨论】:

      【解决方案2】:
      min_element(map.begin(), map.end(),
                  compose2(less<short>(),
                           compose1(select1st<pair<short, float> >(),
                                    select2nd<map<int, pair<short, float>
                                                 >::value_type>()),
                           compose1(select1st<pair<short, float> >(),
                                    select2nd<map<int, pair<short, float>
                                                 >::value_type>()))
                 ).second.first;
      

      (当然,有人会抱怨这是对 STL 的滥用,而且这些扩展不属于 C++ 标准……)

      【讨论】:

      • 好吧,我会抱怨非标准扩展,但就“STL 滥用”而言,我认为这很好:) +1。幸运的是,非标准位很容易自己编写。
      【解决方案3】:

      bind 自己无法做到这一点,因为 firstsecond 被公开为字段,而不是方法(因此您无法摆脱 mem_fun 之类的东西)。

      当然,您可以使用自己的函子来做到这一点:

      template <typename F, typename S>
      struct select_first : std::binary_function<std::pair<F, S>&, F&>
      {
          F& operator()(std::pair<F, S>& toConvert)
          {
              return toConvert.first;
          }
      };
      

      【讨论】:

      • 在某些 C++ 库中也称为select1st
      • @ephemient:是的——不知道它已经包含在 SGI 的 STL 中。在这种情况下,我建议以这种方式保留名称,因为 SGI 支持任何类似对的接口,而这个仅适用于 std::pair。
      猜你喜欢
      • 1970-01-01
      • 2020-01-22
      • 2011-02-08
      • 2022-11-18
      • 2013-07-16
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 2022-10-14
      相关资源
      最近更新 更多