2012-03-08 3 views
0

Я хочу использовать boost::bind для создания boost::function, вставив новую пару ключ-значение в boost::unoredered_map, но у меня мало ошибок компиляции.boost :: bind и insert of boost :: unordered_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> > > >)' 
+0

Не могли бы вы указать свою версию компилятора, пожалуйста? Некоторые старые компиляторы, которые не понимают частичную специализацию, не могут принять указатель на функцию-член в качестве первого аргумента для 'boost :: bind'. –

ответ

1

Проблема в том, что boost::unordered_map содержит более одного insert, так &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, вы можете избежать проблемы с лямбда :

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

Неужели я не говорю, что ваше решение использует static_cast <> быстрее? Используя static_cast <>, неоднозначность разрешается во время компиляции, поэтому, даже если она длиннее, она делает вызов более быстрым, не правда ли? –

+0

Теоретически 'static_cast' будет быстрее (это эквивалентно моему примеру), но некоторые компиляторы могут оптимизировать тривиальную функцию, поэтому оба они могут получить одинаковый результат. –

+0

Auch..I нашел это .. это должно быть & obj как второй аргумент –

1

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) 
); 
+0

Привет, Дэн. Я читаю страницу, которую вы предлагаете, и теперь я понимаю, почему привязка не работает. Большое спасибо. –

Смежные вопросы