メンバー関数でスレッドを開始 質問する

メンバー関数でスレッドを開始 質問する

std::thread引数を取らず を返すメンバー関数を使用して を構築しようとしています。 動作する構文がわかりません。 コンパイラは何をしてもエラーを出します。を実行する を返すようにvoid実装する正しい方法は何ですか?spawn()std::threadtest()

#include <thread>
class blub {
  void test() {
  }
public:
  std::thread spawn() {
    return { test };
  }
};

ベストアンサー1

#include <thread>
#include <iostream>

class bar {
public:
  void foo() {
    std::cout << "hello from member function" << std::endl;
  }
};

int main()
{
  std::thread t(&bar::foo, bar());
  t.join();
}

編集: 編集を考慮すると、次のようにする必要があります。

  std::thread spawn() {
    return std::thread(&blub::test, this);
  }

更新:さらにいくつかの点を説明したいと思います。そのうちのいくつかはコメントでも議論されています。

上記の構文はINVOKE定義(§20.8.2.1)に基づいて定義されます。

INVOKE (f, t1, t2, ..., tN) を次のように定義します。

  • (t1.*f)(t2, ..., tN) ただし、f はクラス T のメンバー関数へのポインターであり、t1 は型 T のオブジェクトまたは型 T のオブジェクトへの参照または T から派生した型のオブジェクトへの参照です。
  • f がクラス T のメンバー関数へのポインタであり、t1 が前の項目で説明した型のいずれでもない場合は、((*t1).*f)(t2, ..., tN) となります。
  • N == 1 であり、f がクラス T のメンバー データへのポインターであり、t 1 が T 型のオブジェクトまたは
    T 型のオブジェクトへの参照または
    T から派生した型のオブジェクトへの参照である場合、t1.*f。
  • (*t1).*f (N == 1 かつ f がクラス T のメンバーデータへのポインターであり、t 1 が前の項目で説明した型のいずれでもない場合)。
  • それ以外の場合はf(t1, t2, ..., tN)。

私が指摘したいもう 1 つの一般的な事実は、デフォルトでは、スレッド コンストラクターは渡されたすべての引数をコピーするということです。その理由は、引数が呼び出しスレッドよりも長く存続する必要がある場合があり、引数をコピーすることでそれが保証されるからです。代わりに、実際に参照を渡す場合は、std::reference_wrappercreated byを使用できますstd::ref

std::thread (foo, std::ref(arg1));

これを行うことで、スレッドが引数を操作するときに引数がまだ存在することを保証することを保証することになります。


なお、上記で述べたことはすべて および にも適用できstd::asyncますstd::bind

おすすめ記事