【问题标题】:boost::bind and insert of a boost::unordered_mapboost::bind 并插入 boost::unordered_map
【发布时间】:2012-03-08 17:37:35
【问题描述】:

我想使用boost::bind 创建一个boost::function,将一个新的键值对插入boost::unoredered_map,但编译错误很少。

typedef boost::unordered_map< 
        std::string, std::string > dict_type;


inline void insert( const std::string& key, const std::string& value ){

    typedef std::pair<dict_type::iterator, bool> out_type;

    dict_type::value_type to_insert(key,value);

    boost::function<void()> f = boost::bind<out_type>( 
        &dict_type::insert
        ,obj_
        ,boost::cref(to_insert)
    );
}

下面的错误看起来像bind 找不到unordered_map::insert 的正确重载。在这种情况下,我指定了正确的重载,但这次它不起作用。你知道它是什么吗?

 ../include2/llve_clorder_id.h:32: error: no matching function for call to 
'bind(<unresolved overloaded function type>,
 boost::unordered_map<std::basic_string<char, std::char_traits<char>, 
 std::allocator<char> >, std::basic_string<char, std::char_traits<char>, 
 std::allocator<char> >, boost::hash<std::basic_string<char, std::char_traits<char>,   
 std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, 
 std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, 
 std::char_traits<char>, std::allocator<char> >, std::basic_string<char, 
 std::char_traits<char>, std::allocator<char> > > > >&, const 
 boost::reference_wrapper<const std::pair<const std::basic_string<char, 
 std::char_traits<char>, std::allocator<char> >, std::basic_string<char, 
 std::char_traits<char>, std::allocator<char> > > >)'

【问题讨论】:

  • 您能指定您的编译器版本吗?一些不理解偏特化的旧编译器不能接受指向函数成员的指针作为boost::bind 的第一个参数。

标签: c++ boost-bind boost-function


【解决方案1】:

问题是boost::unordered_map 包含多个insert,所以&amp;dict_type::insert 是不明确的。最简单的解决方案是定义一个函数来调用正确的重载:

void insert(dict_type & dict, dict_type::value_type const & value) {
    dict.insert(value);
}

boost::function<void()> f = boost::bind( 
    insert
    ,boost::ref(obj_)
    ,boost::cref(to_insert)
);

或者您可以明确指定重载:

boost::function<void()> f = boost::bind( 
    static_cast<out_type (dict_type::*)(dict_type::value_type const &)>(&dict_type::insert)
    ,obj_
    ,boost::cref(to_insert)
);

在 C++11 中,您可以避免使用 lambda 的问题:

std::function<void()> f = [&](){obj_.insert(to_insert);};

【讨论】:

  • 我错了说您的解决方案使用 static_cast 更快吗?通过使用 static_cast 歧义在编译时得到解决,因此即使编写时间更长,它也会更快地调用绑定,不是吗?
  • 理论上static_cast 会更快(它相当于我的示例),但是一些编译器可能能够优化出琐碎的函数,因此它们可能会给出相同的结果。
  • Auch..我找到了..它应该是 &obj 作为第二个参数
【解决方案2】:

http://www.boost.org/doc/libs/1_49_0/libs/bind/bind.html#Troubleshooting 建议您有时可以通过将指向成员函数的指针转换为所需类型来解决重载函数的问题。使用一个临时变量来阻止它变得完全不可读,它看起来像:

typedef std::pair<typename dict_type::iterator, bool> out_type;

typename dict_type::value_type to_insert(key,value);

out_type (dict_type::*ins) (typename dict_type::value_type const&) const = &dict_type::insert;

boost::function<void()> f = boost::bind(
    ins
    ,obj_
    ,boost::cref(to_insert)
);

【讨论】:

  • 嗨,丹。我阅读了您建议的页面,现在我更好地理解了为什么 bind 不起作用。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2010-12-09
  • 2023-04-07
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2011-05-16
  • 2016-03-16
  • 1970-01-01
相关资源
最近更新 更多