我已经尝试过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);
答案 0 :(得分:2)
您必须提供async
模板参数。不仅要绑定一个 async
。每个函数模板的实例化都有一个。
答案 1 :(得分: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<...>
(因此{{1} }})。无法推断std::bind
将返回的内容。所以我们明确说明了返回类型:
chosen_async
所有这些似乎足以让GCC满意,至少:http://ideone.com/gapLs。
当然,你可以用lambda表达式来节省很多麻烦:
auto async_bound=
std::bind<std::future<foo_rettype>>(chosen_async,
make_adv(std::forward<foo_type>(&foo)));