Boost.Bind访问std :: for_each中的std :: map元素

时间:2010-02-22 15:09:18

标签: c++ boost bind stdmap foreach

我有一张存储带键的简单结构的地图。该struct有两个成员函数,一个是const而另一个不是。我已经使用std :: for_each来管理const函数而没有任何问题,但是我在调​​用非const函数时遇到了一些问题。

struct MyStruct {
  void someConstFunction() const;
  void someFunction();
};

typedef std::map<int, MyStruct> MyMap;
MyMap theMap;

//call the const member function
std::for_each(theMap.begin(), theMap.end(),
   boost::bind(&MyStruct::someConstFunction, boost::bind(&MyMap::value_type::second, _1)));

//call the non-const member function
std::for_each(theMap.begin(), theMap.end(),
   boost::bind(&MyStruct::someFunction, boost::bind(&MyMap::value_type::second, _1)));

对const成员函数的调用工作正常,但似乎boost内部需要一个const MyStruct,因此在MSVC7.1中出现以下编译错误。

  

boost \ bind \ mem_fn_template.hpp(151):错误C2440:'参数':无法从'const MyStruct * __ w64'转换为'MyStruct * const'

我非常感谢有关如何正确设置模板参数的任何帮助,因此bind会正确识别参数并让我调用非const函数。

感谢, 卡尔

4 个答案:

答案 0 :(得分:8)

IIRC,Boost.Bind使用boost::mem_fn来绑定成员功能。现在,如果你看一下mem_fun(向下滚动到// data member support部分),你会看到它将type_fs的result_type定义为const&amp;,同时仍然有函数调用运算符的重载支持从非const参数中提取非const成员。

因此,问题似乎是混淆了Boost.Bind的返回类型演绎机制。因此,解决方案将明确告诉Bind结果不是const:

//call the non-const member function
std::for_each(theMap.begin(), theMap.end(),
   boost::bind(&MyStruct::someFunction, 
       boost::bind<MyStruct&>(&MyMap::value_type::second, _1)
   )
);

答案 1 :(得分:7)

如果您发现自己必须这么做,我建议您使用Boost.RangeEx库:

#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/mem_fn.hpp>
#include <map>

struct MyStruct {
  void someConstFunction() const;
  void someFunction();
};

typedef std::map<int, MyStruct> MyMap;
MyMap theMap;

int main()
{
    //call the const member function
    boost::for_each(theMap | boost::adaptors::map_values,
                    boost::mem_fn(&MyStruct::someConstFunction));

    //call the non-const member function
    boost::for_each(theMap | boost::adaptors::map_values,
                    boost::mem_fn(&MyStruct::someFunction));
}

它已被Boost接受,但尚未附带官方发行版。在此之前,您可以download it(下载链接到zip文件)Boost Vault

答案 2 :(得分:4)

如果您已经依赖Boost,则可能愿意查看Boost Foreach

BOOST_FOREACH(MyMap::value_type const& val, MyMap)
{
  val.second.someConstFunction();
}

虽然我不了解性能问题,但可读性很强。

另请注意,如果不“转义”,字符,则无法在宏中使用模板化输入:

  • 或者是
  • 之前的typedef
  • 或使用类型
  • 周围的第二对括号

答案 3 :(得分:0)

我发现了一个问题:第二个绑定是为非函数成员调用的。 second是数据成员,而不是std :: pair

的方法