使用boost :: bind迭代std :: map

时间:2012-02-26 13:15:43

标签: c++ boost stl map bind

我做了一个小例子,以了解boost::bind ()如何使用集合。我有一个名为Data的课程:

class Data
{
public:
    void print ();
    const std::string& get () const;
    std::string& get () ;
};

我创建了一个名为samples的std::vector数据对象,我可以像bind一样使用std::mem_fun_ref

std::for_each (samples.begin (),samples.end (),std::mem_fun_ref (&Data::print));
std::for_each (samples.begin (),samples.end (),boost::bind (&Data::print,_1));

基本思想是bind返回类型为bind_t<RetType=void, ObjType=Data, ArgType=void>的函数对象。作为第一个参数的成员函数允许编译器推导出RetTypeObjTypeArgType。占位符_1对应于算法必须提供的数据对象。

然后std::for_each以下列方式调用“for each”元素的函数对象:

for ( ; first!=last; ++first ) f(*first);

bind_t::operator(ObjType& obj)被调用,其定义应该是这样的:

return (obj.*_method ());

我创建了一个名为Filter的类,它对数据元素执行一些处理。

class Filter
{
    void filter (Data& data);
    ...
};

如果我想对向量中的数据元素应用过滤器,请按以下方式调用bind

std::for_each (samples.begin (),samples.end (),boost::bind (&Filter::filter,filter,_1));

for_eachData个对象传递给bind_t::operator()。在这种情况下,函数对象已经有了对象,只需要参数,所以在这种情况下,占位符_1引用参数。

我的问题出现了:

如果必须迭代bind而不是向量,如何使用std::map

(抱歉所有的解释,我只是想确保我理解bind的工作方式)

2 个答案:

答案 0 :(得分:2)

#include <boost/bind.hpp>
#include <algorithm>
int main()
{
  struct Sample
  {
    int i_;
    double d_;
  };
  typedef std::map<int, Sample> Samples;
  struct Filter
  {
    void filter(const Sample &s)
    {
    }
  };
  Filter filter;
  Samples samples;
  std::for_each(samples.begin(), samples.end(), boost::bind(&Filter::filter, filter, boost::bind(&Samples::value_type::second, _1))); 
}

答案 1 :(得分:0)

当然,您可以使用bind()来迭代std::map<...>。但是,请注意std::map<K, V>中的元素具有类型std::pair<K const, V>,即绑定函数需要是访问此类对象的电缆。也就是说,我不知道单独使用bind()可以将此参数转换为您实际感兴趣的参数(即V)。为此,您可能需要一个辅助函数来调用它来进行转换。如果你bind()这个函数以及bind()可以做一个合适的组合,即我认为这样的事情应该有效:

template <typename Result>
struct project2nd {
    typedef Result const& result_type;
    template <typename T>
    result_type operator()(std::pair<T, Result> const& arg) const {
        return arg.second;
    }
};
...
... bind(&Filter::filter, filter, bind(project2nd<Data>(), _1)) ...

对于bind()使用funciton对象,它似乎需要一些关于相关类型的信息:函数调用运算符的结果不能推导出来,但显然需要在内部。我假设bind()足够聪明,可以传递引用。否则,需要将类型更改为Result。另外,我不知道bind()是否也需要了解论证类型。如果是这样,project2nd类tmeplate将需要将两种类型作为参数。