【发布时间】:2011-01-25 15:43:54
【问题描述】:
我有std::map<int, std::pair<short, float> >,我需要在这张地图中找到最小的short。为此,我如何使用boost::bind 和std::min_element()?
boost::lambda?
【问题讨论】:
标签: c++ boost-bind boost-lambda
我有std::map<int, std::pair<short, float> >,我需要在这张地图中找到最小的short。为此,我如何使用boost::bind 和std::min_element()?
boost::lambda?
【问题讨论】:
标签: c++ boost-bind boost-lambda
map 迭代器会给你一个pair,其中first 是int 键,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<。 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。
【讨论】:
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++ 标准……)
【讨论】:
bind 自己无法做到这一点,因为 first 和 second 被公开为字段,而不是方法(因此您无法摆脱 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;
}
};
【讨论】:
select1st。