【问题标题】:c++0x std::function as a method argumentc++0x std::function 作为方法参数
【发布时间】:2011-10-26 22:30:00
【问题描述】:

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

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

这按预期工作。但是,我希望将参数传递给作为任务提供的某些方法,但不希望为所有不同的 function&lt; ... &gt; 表单创建重载。

例如,是否有可能只创建一个如下所示的方法

deliver( std::function& task );

只需调用

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

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

等等……

感谢大家的意见。看来我真正的错是对dispatch-&gt;deliver 的调用,而附加参数也是绑定调用。

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

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

【问题讨论】:

  • 类声明后缺少;。 :-)

标签: c++ function bind c++11


【解决方案1】:

std::function&lt;void(void)&gt; 已经是多态的,这就是它的全部意义所在。所以最后两个 sn-ps 可以工作(只要函数 bind 可以在没有参数的情况下调用返回,当然也不返回任何内容),而不会改变你已经拥有的东西。

【讨论】:

    【解决方案2】:

    可以,只要你使用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;
    }
    

    (注意,我使用的是Boost.Function和Boost.Bind,但使用std::bind和std::function应该没有区别。)

    【讨论】:

    【解决方案3】:
    class dispatch
    {
      public:
         template <typename ... Params>
         deliver( std::function<void (Params && p...)> task, Params && p )
         {
             task(std::forward(p)...);
         }
    };
    

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

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

    我不清楚的一件事是,如果 Object::method 具有默认参数而不是重载,它的行为方式。

    【讨论】:

    • +1:挑剔,将 std::function 作为 const 引用传递可能更有效。
    • @DirkM 你是对的,但由于 OP 没有这样做,我也选择不这样做。他可能正在使用不涉及“交付”的交付方法做一些事情。我希望不会。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 2021-01-13
    • 2021-07-12
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多