函数作为方法参数

时间:2023-01-06 14:37:21

I'm attempting to pass a std::function via a method like so:

我正在尝试通过如下方法传递std:::函数:

class dispatch
{
  public:
     deliver( std::function<void ( void )> task );
}

This works as expected. However i wish to pass arguments to some of the methods supplied as the task but would prefer not to have to create overloads for all the different function< ... > forms.

这是预期。但是,我希望将参数传递给作为任务提供的一些方法,但是不希望为所有不同的函数<…>形式。

for example is it at all possible just to create a method like follows

例如,仅仅创建如下所示的方法是完全可能的

deliver( std::function& task );

and just invoke with

和只是调用

dispatch->deliver( bind( &Object::method, X ) );

or

dispatch->deliver( bind( &Object::method, X, arg1, arg2 ) );

etc...

等等……

Thanks for everyones input. It would appear my real fault is with calls to dispatch->deliver with the additional argument also being a bind call.

谢谢大家的意见。我的真正的缺点是,通过调用分派->来传递额外的参数也是一个绑定调用。

dispatch->deliver( bind( &Object::method1, X1, bind( &Object::method1, X2 ) );

error: /usr/include/c++/v1/functional:1539:13: error: no matching function for call to '__mu_expand' return __mu_expand(__ti, __uj, __indices());

错误:/usr/include/c++/v1/functional:1539:13: error:没有调用“__mu_expand”的匹配函数返回__mu_expand(__ti, __uj, __indices();

3 个解决方案

#1


10  

std::function<void(void)> is already polymorphic, that's the whole point of it. So those two last snippets will work (as long as the functor bind returns can be called with no arguments, and returns nothing, of course), without changing what you already have.

函数 已经是多态的,这就是它的全部意义。因此,这最后的两个片段将会工作(只要函数绑定返回可以在没有参数的情况下被调用,并且当然不会返回任何内容),而不会更改您已经拥有的内容。 (void)>

#2


3  

Yes, it is possible as long as you use bind to generate compatible function objects:

是的,只要您使用bind(绑定)生成兼容的函数对象就可以:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <list>
#include <string>

typedef boost::function<void(void)> fun_t;
typedef std::list<fun_t> funs_t;

void foo()
    { std::cout <<"\n"; }
void bar(int p)
    { std::cout<<"("<<p<<")\n"; }
void goo(std::string const& p)
    { std::cout<<"("<<p<<")\n"; }

void caller(fun_t f)
    { f(); }

int main()
{
    funs_t f;
    f.push_front(boost::bind(foo));
    f.push_front(boost::bind(bar, int(17)));
    f.push_front(boost::bind(goo, "I am goo"));

    for (funs_t::iterator it = f.begin(); it != f.end(); ++it)
    {
        caller(*it);
    }

    return 0;
}

(Note, I use Boost.Function and Boost.Bind, but there should be no difference to use of std::bind and std::function.)

(注意,我使用的提升。功能和提高。绑定,但是使用std:: Bind和std::function应该没有区别。

#3


1  

class dispatch
{
  public:
     template <typename ... Params>
     deliver( std::function<void (Params && p...)> task, Params && p )
     {
         task(std::forward(p)...);
     }
};

I haven't compiled this (corrections welcome!), but the idea should work.

我还没有编译这个(更正,欢迎!),但是这个想法应该是可行的。

dispatch->deliver( bind( &Object::method, X ) );
dispatch->deliver( bind( &Object::method, X, arg1, arg2 ) ); // OR!
dispatch->deliver( bind( &Object::method, X ), arg1, arg2 );

The one thing I'm unclear about is how this behaves if Object::method has defaulted params instead of overloads.

我不清楚的一件事是,如果Object::方法已经默认了参数,而不是重载。

#1


10  

std::function<void(void)> is already polymorphic, that's the whole point of it. So those two last snippets will work (as long as the functor bind returns can be called with no arguments, and returns nothing, of course), without changing what you already have.

函数 已经是多态的,这就是它的全部意义。因此,这最后的两个片段将会工作(只要函数绑定返回可以在没有参数的情况下被调用,并且当然不会返回任何内容),而不会更改您已经拥有的内容。 (void)>

#2


3  

Yes, it is possible as long as you use bind to generate compatible function objects:

是的,只要您使用bind(绑定)生成兼容的函数对象就可以:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <list>
#include <string>

typedef boost::function<void(void)> fun_t;
typedef std::list<fun_t> funs_t;

void foo()
    { std::cout <<"\n"; }
void bar(int p)
    { std::cout<<"("<<p<<")\n"; }
void goo(std::string const& p)
    { std::cout<<"("<<p<<")\n"; }

void caller(fun_t f)
    { f(); }

int main()
{
    funs_t f;
    f.push_front(boost::bind(foo));
    f.push_front(boost::bind(bar, int(17)));
    f.push_front(boost::bind(goo, "I am goo"));

    for (funs_t::iterator it = f.begin(); it != f.end(); ++it)
    {
        caller(*it);
    }

    return 0;
}

(Note, I use Boost.Function and Boost.Bind, but there should be no difference to use of std::bind and std::function.)

(注意,我使用的提升。功能和提高。绑定,但是使用std:: Bind和std::function应该没有区别。

#3


1  

class dispatch
{
  public:
     template <typename ... Params>
     deliver( std::function<void (Params && p...)> task, Params && p )
     {
         task(std::forward(p)...);
     }
};

I haven't compiled this (corrections welcome!), but the idea should work.

我还没有编译这个(更正,欢迎!),但是这个想法应该是可行的。

dispatch->deliver( bind( &Object::method, X ) );
dispatch->deliver( bind( &Object::method, X, arg1, arg2 ) ); // OR!
dispatch->deliver( bind( &Object::method, X ), arg1, arg2 );

The one thing I'm unclear about is how this behaves if Object::method has defaulted params instead of overloads.

我不清楚的一件事是,如果Object::方法已经默认了参数,而不是重载。