我有一张存储带键的简单结构的地图。该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函数。
感谢, 卡尔
答案 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();
}
虽然我不了解性能问题,但可读性很强。
另请注意,如果不“转义”,
字符,则无法在宏中使用模板化输入:
答案 3 :(得分:0)
我发现了一个问题:第二个绑定是为非函数成员调用的。 second是数据成员,而不是std :: pair
的方法