8

我有一个地图,它存储一个带有键的简单结构。该结构有两个成员函数,一个是 const 另一个不是。我已经成功地使用 std::for_each 调用了 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: 'argument' : 无法从 'const MyStruct *__w64 ' 转换为 'MyStruct *const '

我将不胜感激有关如何正确设置模板参数的任何帮助,因此 bind 确实可以正确识别参数并让我调用非 const 函数。

谢谢,卡尔

4

4 回答 4

8

IIRC,Boost.Bindboost::mem_fn用于绑定到成员的能力。现在,如果您查看mem_fun(向下滚动到该// data member support部分),您会看到它将其 result_type 类型定义为 const&,而 is 仍然具有支持从 non-const 中提取 non-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)
   )
);
于 2010-02-22T16:19:06.633 回答
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 接受,但尚未随官方发行版一起提供。在它完成之前,您可以 从Boost Vault下载它(下载链接到 zip 文件)。

于 2010-02-22T15:45:33.457 回答
4

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

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

可读性很强,虽然我不知道性能问题。

,另请注意,如果不“转义”字符,则不能使用在宏中键入的模板:

  • 之前的 typedef
  • 或通过在类型周围使用第二对括号
于 2010-02-22T15:35:28.907 回答
0

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

于 2010-02-22T15:18:18.947 回答