3

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

void foo() {}

auto f = bind(async, foo);

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

编辑:

感谢您的建议,但以下均无效(使用任何编译器):

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

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

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

2 回答 2

2

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, &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(&foo))),除了一个问题:您不能直接传递std::async我们的包装对象之一,因此std::result_of<...>(因此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);};
于 2012-06-21T05:56:37.200 回答
2

您必须提供async模板参数。不只有一个 async可以绑定。函数模板的每个实例都有一个。

于 2012-06-20T17:20:09.590 回答