2016-05-11 2 views
1

Я пытаюсь добиться чего-то вроде этого, но получение ошибок, связанных с подталкивание связываютКак использовать повышение :: правильно связать с картой функции указателей

#include <map> 
#include "boost/assign.hpp" 
#include <boost/foreach.hpp> 
#include <string> 
#include <boost/function.hpp> 
#include <boost/bind.hpp> 


struct myStruct_t 
{ 
    int getInt() {return 1;}; 
}; 

int foo( myStruct_t* m, std::string str) 
{ 
    if(str == "A") 
    { 
     return m->getInt(); 
    } 
    else if (str == "B") 
    { 
     return 2; 
    } 
    else 
    { 
     return 3; 
    } 
} 

typedef std::map<std::string, boost::function<int(myStruct_t*, std::string)> > Map_t; 

Map_t myMap = boost::assign::map_list_of ("Jake", boost::bind((&foo, _1), "A") 
             ("Ken", boost::bind((&foo, _1), "B") 
             ("Pete", boost::bind((&foo, _1), "C"); 



int main() 
{ 
    std::vector<std::string> myVal; 
    myVal.push_back("Jake"); 
    myVal.push_back("Ken"); 
    myVal.push_back("Pete"); 

    myStruct_t myStruct; 
    BOOST_FOREACH(const std::string& aStr, myVal) 
    { 
     Map_t::const_iterator iter = myMap.find(aStr); 
     if(iter != myMap.end()) 
     { 
      int myInt = (iter->second)(myStruct); 
     } 
    } 
    return 0; 
} 

Ошибки я получаю являются

In file included from /usr/local/boost-1.60.0/include/boost/bind.hpp:22:0, 
       from prog.cc:6: 
/usr/local/boost-1.60.0/include/boost/bind/bind.hpp: In instantiation of 'boost::_bi::result_traits<boost::_bi::unspecified, boost::arg<1> >': 
/usr/local/boost-1.60.0/include/boost/bind/bind.hpp:1212:48: instantiated from 'boost::_bi::bind_t<boost::_bi::unspecified, boost::arg<1>, boost::_bi::list1<boost::_bi::value<const char*> > >' 
prog.cc:32:81: instantiated from here 
/usr/local/boost-1.60.0/include/boost/bind/bind.hpp:75:37: error: no type named 'result_type' in 'struct boost::arg<1>' 
prog.cc:34:82: error: expected ')' before ';' token 
prog.cc: In function 'int main()': 
prog.cc:50:48: error: no match for call to '(const boost::function<int(myStruct_t*, std::basic_string<char>)>) (myStruct_t&)' 
/usr/local/boost-1.60.0/include/boost/function/function_template.hpp:765:17: note: candidate is: result_type boost::function2<R, T1, T2>::operator()(T0, T1) const [with R = int, T0 = myStruct_t*, T1 = std::basic_string<char>, result_type = int] 

Кажется, я озадачен тем, как используется boost :: bind. Может кто-нибудь, пожалуйста, помогите мне сделать это правильно? Большое спасибо.

+0

У вас есть дополнительный набор скобок в 'повышение :: Bind ((& foo, _1), "A") 'и все остальные. Удалить их. –

+0

Кроме того, тип 'Map' должен быть' boost :: function ' –

+0

Убрал дополнительную скобку и изменил карту на boost :: function . Все еще получаю ошибку – polapts

ответ

2

Функция подписи ожидается на месте вызова является Int (MyStruct *)

из-за этой линии (я добавил & удалить логическую ошибку):

int myInt = (iter->second)(&myStruct); 

в этом случае декларация на карте должно быть указано:

typedef std::map<std::string, boost::function<int(myStruct_t*)> > Map_t; 

Map_t myMap = boost::assign::map_list_of 
("Jake", boost::bind(&foo, boost::placeholders::_1, std::string("A"))) 
("Ken", boost::bind(&foo, boost::placeholders::_1, std::string("B"))) 
("Pete", boost::bind(&foo, boost::placeholders::_1, std::string("C"))); 

И тогда вам хорошо идти.

объяснение:

импульс [станд] :: привязывать возвращает объект-функцию, которая предназначена, чтобы принимать только те параметры, которые указаны в качестве заполнителей в выражении bind.

Это означает, что функция, которая, наконец, называется часто имеют больше аргументов, чем функции объекта, возвращенного bind

так в вашем случае, foo имеет следующую подпись:

int foo( myStruct_t* m, std::string str) 

т.е. принимает два аргументы и возвращает int.

Однако в момент вызова bind:.

boost::bind(&foo, boost::placeholders::_1, std::string("A")) 

Что мы говорим, является «захват функции foo и второй аргумент (строку) Возвращайтесь мне функциональный объект, который требует один аргумент (_1) и вперед этот аргумент в качестве первого аргумента foo при прохождении связанной строки в качестве второго аргумента

так дано:.

auto f = boost::bind(&foo, boost::placeholders::_1, std::string("A")); 

f имеет подпись int f(MyStruct*)

и при вызове с

auto i = f(&mystruct); 

это эквивалентно вызову:

auto i = foo(&mystruct, std::string("A")); 
+0

Спасибо. Он работал хорошо.Я могу понять одну проблему, что функция ожидала указатель, и я передавал объект. Но функция int foo (myStruct_t * m, std :: string str) ожидает два параметра myStruct_t и std :: string. Тогда почему функция boost :: function имеет только один параметр в объявлении? – polapts

+0

@polapts обновлено с более длинным объяснением. Надеюсь, это полезно. –

+0

Excellet! Большое спасибо. – polapts

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