3

私はいくつかのコード (GitHub の progschj の厚意による) を持っています。MakeTask は、すべての関数とその引数を MakeTask に移動し、packaged_task を作成します。作成されたタスクが実行され、その未来が呼び出し元に返されます。これは非常に洗練されていますが、メンバー関数でもこれを実行できるようにしたいと考えています。しかし、Func を構造体に入れると、MakeTask の F&& はコードに記載されているエラーで失敗します。

#include <future>
#include <memory>
#include <string>
#include <functional>

template<class F, class... Args>
auto MakeTask( F&& f, Args&&... args )-> std::future< typename std::result_of< F( Args... ) >::type >
{
  typedef typename std::result_of< F( Args... ) >::type return_type;

  auto task = std::make_shared< std::packaged_task< return_type() > >(
    std::bind( std::forward< F >( f ), std::forward< Args >( args )... )
    );

  std::future< return_type > resultFuture = task->get_future();

  ( *task )( );

  return resultFuture;
}

struct A
{
  int Func( int nn, std::string str )
  {
    return str.length();
  }
};

int main()
{
  // error C2893: Failed to specialize function template 'std::future<std::result_of<_Fty(_Args...)>::type> MakeTask(F &&,Args &&...)'
  // note: 'F=int (__thiscall A::* )(int,std::string)'
  // note: 'Args={int, const char (&)[4]}'
  auto resultFuture = MakeTask( &A::Func, 33, "bbb" );  // does not compile

  int nn = resultFuture.get();

  return 0;
}

Func を静的に変更すれば機能させることができますが、アプリ コードの他の部分が壊れてしまいます。

Edit1: std::function の構文を理解し、新しいエラー メッセージでサンプルを修正しました。MakeTask の F&& move 引数は、私の aFunc を呼び出し可能なオブジェクトとして受け入れません。

Edit2: Barry の回答のため、サンプル コードを元の投稿に戻して、彼の回答が将来の視聴者にとって意味のあるものになるようにします。

4

1 に答える 1

3

&A::Funcは非静的メンバー関数です。つまり、A操作には のインスタンスが必要です。すべての関数オブジェクト/アダプターが使用する規則は、提供される最初の引数がそのインスタンスになるというものです。

MakeTask()では、最初の引数 ( F) が他のすべての引数 ( Args...) と共に呼び出し可能である必要があります。型のオブジェクト(またはまたはへのポインター)、、および の3 つの&A::Func引数が必要です。あなたは単に最初のものを見逃しています:AAreference_wrapper<A>intstring

auto resultFuture = MakeTask( &A::Func, A{}, 33, "bbb" );
                                       ^^^^^
于 2016-07-15T20:49:41.020 に答える