【问题标题】:How to bind async?如何绑定异步?
【发布时间】:2012-06-20 17:16:31
【问题描述】:

我已经用 VS、g++ 和 Clang 尝试了以下操作,但无法确定任何喷出的错误的韵律或原因。

void foo() {}

auto f = bind(async, foo);

我怀疑错误可能源于混淆 async() 绑定到哪个,一个采用启动策略与一个不采用启动策略...或者我必须明确地为 async() 提供其模板类型(例如异步<...>)?无论哪种方式,写上面的语句的正确方法是什么?

编辑:

感谢您的建议,但以下都不起作用(使用任何编译器):

bind(async<decltype(foo)>, foo);

bind(async<void (*)()>, foo);

bind(async<function<void ()> >, foo);

【问题讨论】:

  • 是的,您需要传递模板参数。我只会使用 lambda 并忘记绑定。
  • 也许可以试试async&lt;decltype(foo)&gt;

标签: c++ c++11


【解决方案1】:

std::async 不仅是一个模板,而且它也是重载的。您不仅需要选择所需的模板,还需要选择重载模板。

 typedef decltype(&foo) foo_type;
 typedef std::result_of<foo_type()>::type foo_rettype;

 auto chosen_async=
   static_cast<std::future<foo_rettype> (*)(foo_type && )>
     (&std::async<foo_type>);

不幸的是,std::bind 似乎不允许绑定函数采用右值引用。所以只写std::bind(chosen_async, &amp;foo) 仍然行不通。 Is there a reference_wrapper<> for rvalue references? 中讨论了此问题的解决方法:

template<typename T> struct adv { 
  T t; 
  explicit adv(T &&t):t(std::forward<T>(t)) {} 
  template<typename ...U> T &&operator()(U &&...) { 
    return std::forward<T>(t); 
  } 
}; 

template<typename T> adv<T> make_adv(T &&t) { 
  return adv<T>{std::forward<T>(t)}; 
}

namespace std { 
  template<typename T> 
  struct is_bind_expression< adv<T> > : std::true_type {}; 
} 

我们可以通过说std::bind(chosen_async, make_adv(std::move(&amp;foo))) 来完成,除了一个问题:你不能直接传递std::async 我们的包装对象之一,因此std::result_of&lt;...&gt;(因此std::bind)。无法推断 chosen_async 将返回什么。所以我们明确声明返回类型:

auto async_bound=
    std::bind<std::future<foo_rettype>>(chosen_async, 
                                        make_adv(std::forward<foo_type>(&foo)));

做这一切似乎足以让 GCC 高兴,至少:http://ideone.com/gapLs


当然,使用 lambda 表达式可以省去很多麻烦:

auto async_bound=[=]()->std::future<void> {return std::async(&foo);};

【讨论】:

  • 它现在运行。也超级丑。有人建议只使用 lambda 表达式吗? ;-)
  • @Managu 感谢您进行了艰苦的调查工作(并表明它不是“给它模板参数”那么简单)。现在,说实话,当我偶然发现那个“问题”时,我有点走神了。我对此没有“现实世界”的需求。我试图看看我是否可以得到像 auto f = bind(async, foo, _1); 这样的东西f(11).get(); f(22).get(); (那是压缩版)。在您回答之后,我不确定它是否可以优雅地完成......但是,您的回答可能会在以后使某人受益。那个人可能是你或我。 :)
  • @screwnut:我也这么认为。并且 lambdas 仍然更好:auto fooasync=[=](int i)-&gt;decltype(async(&amp;foo, i)) {return async(&amp;foo, i);}
【解决方案2】:

你必须给async模板参数。不只是一个 async 可以绑定。函数模板的每个实例都有一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多