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)
まだ機能しません。この問題の回避策については、右辺値参照用のreference_wrapper <>はありますか?で説明されています。:
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)))
1つの問題を除いて、次のように言うことで完了します。std::async
ラッパーオブジェクトの1つを直接渡すことはできず、その結果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。
もちろん、ラムダ式を使用すると、面倒な作業を大幅に節約できます。
auto async_bound=[=]()->std::future<void> {return std::async(&foo);};