1. ホーム
  2. c++

[解決済み】メンバ関数でスレッドを開始する

2022-04-30 05:17:16

質問

を構築しようとしています。 std::thread を返すメンバ関数で、引数を取らずに void . どのような構文を使っても、コンパイラは文句を言うのです。を実装する正しい方法は何でしょうか? spawn() を返すように std::thread を実行する test() ?

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

解決方法は?

#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();
}

EDIT 編集したものを会計処理する、このようにしなければなりません。

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


UPDATEです。 コメント欄でも議論されていることですが、もう少し説明したいと思います。

上記の構文は、INVOKE定義(§20.8.2.1)の観点で定義されています。

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

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

    のオブジェクトへの参照、またはT型のオブジェクトへの参照。

    型はTから派生したものである。
  • (*t1).*f N == 1で、fがクラスTのメンバデータへのポインタであり、t1が前項で述べた型のいずれでもないとき。
  • その他の場合はf(t1, t2, ..., tN)。

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

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

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


上記で述べたことはすべて std::asyncstd::bind .