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)まだ機能しません。この問題の回避策については、右辺値参照用の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);};
于 2012-06-21T05:56:37.200 に答える
2

asyncテンプレートパラメータを指定する必要があります。バインドするのは1つ だけではありません。async関数テンプレートのインスタンス化ごとに1つあります。

于 2012-06-20T17:20:09.590 に答える