简体   繁体   English

如何正确使用boost ::: bind和函数指针映射

[英]How to use boost::bind correctly with a map of function pointers

I am trying to achieve something like this but getting boost bind related errors 我正在尝试实现类似的操作,但出现与增强绑定相关的错误

#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;
}

The errors I am getting are 我得到的错误是

   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]

It seems I am puzzled the way boost::bind is used. 似乎我对使用boost :: bind的方式感到困惑。 Can someone please help me doing it correctly? 有人可以帮我正确地做吗? Many Thanks. 非常感谢。

The function signature expected at the call site is int(myStruct*) 调用站点上预期的函数签名为int(myStruct *)

because of this line (I added the & to remove a logic error): 由于这一行(我添加了&来删除逻辑错误):

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

in which case the declaration of the map should be: 在这种情况下,地图的声明应为:

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")));

And then you're good to go. 然后您就可以开始了。

explanation: 说明:

boost[std]::bind returns a function object which is designed to accept only the parameters that are mentioned as placeholders in the bind expression. boost [std] :: bind返回一个函数对象,该对象旨在仅接受在bind表达式中作为占位符提及的参数。

This means that the function that is finally called will often have more arguments than the function object returned by bind 这意味着最终调用的函数通常比bind返回的函数对象具有更多的参数。

so in your case, foo has the following signature: 因此,在您的情况下, foo具有以下签名:

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

ie takes two arguments and returns an int. 即接受两个参数并返回一个整数。

However at the point of the call to bind : 但是在bind

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

What we're saying is "capture the function foo and the second argument (a string). Return me a function object that requires one argument ( _1 ) and forward that argument as the first argument to foo while passing the bound string as the second argument. 我们的意思是“捕获函数foo和第二个参数(字符串)。返回给我一个需要一个参数( _1 )的函数对象,并将该参数作为第一个参数转发给foo同时将绑定的字符串作为第二个参数传递论点。

so given: 因此给出:

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

f has the signature int f(MyStruct*) f具有签名int f(MyStruct*)

and when called with 当与

auto i = f(&mystruct);

it is equivalent to calling: 它等效于调用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM