2016-05-11 31 views
1

我想實現這樣的事情,但得到提升綁定相關的錯誤如何使用的boost ::與地圖功能正確綁定指針

#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

您在'提高::綁定((有一個額外的括號&foo,_1),「A」)和所有其他的。刪除它們。 –

+0

另外,'Map'的類型應該是'boost :: function ' –

+0

刪除額外的圓括號並將Map更改爲boost :: function 。仍然收到錯誤 – polapts

回答

2

預期在調用位置的函數簽名是因爲該線(I加入&刪除邏輯錯誤)的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"))); 

然後你很好走。

解釋:

升壓[STD] ::綁定返回其被設計成僅接受被提及作爲在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