8

我有std::map<int, std::pair<short, float> >,我需要short在这张地图中找到最小值。我该如何使用boost::bindwithstd::min_element()这个?

boost::lambda?

4

3 回答 3

6

迭代器map会给你一个pairwherefirstintkey 和secondmap 的pair值,所以如果你有一个 iterator 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<. 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.

于 2011-01-25T16:37:48.487 回答
5
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++ 标准中……)

于 2011-01-25T16:15:53.413 回答
2

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;
    }
};
于 2011-01-25T16:12:56.713 回答