参照渡し時に std::thread がコピー コンストラクターを呼び出す
std::thread を使用してスレッドにデータを渡すと、特に問題が発生する可能性があります。コピー コンストラクターを無効にしたクラスを扱うとき。この動作は、std::thread が引数を値で受け取るという事実から生じています。
コピー コンストラクターが無効になっている次のクラス Log を考えてみましょう。
class Log { public: Log(const char filename[], const bool outputToConsole = false); virtual ~Log(void); // ... private: // Disable copy constructor and assignment operator Log(const Log &); Log &operator=(const Log &); };
メイン関数では、Logオブジェクト ロガーは参照によってサーバー関数に渡されます:
Log logger("ServerLog.txt", true); server(ioService, portNumber, logger);
サーバー関数は、ロガーを引数として使用して新しいスレッドを作成します:
std::thread newThread(session, &sock, logger);
ただし、これによりコンパイラ エラーが発生します。 Log のコピー コンストラクターが無効になっているためです。
参照による受け渡しはコピー コンストラクターを呼び出すのはなぜですか?
一般的な想定に反して、C での参照による受け渡しは、コピー コンストラクターを呼び出すことを妨げません。コピー コンストラクターの呼び出し。参照を渡すとき、コンパイラは参照されたオブジェクトの一時コピーを作成し、それを関数に渡します。これは、std::thread がその引数がコピー可能であることを期待しているためです。
解決策: std::reference_wrapper を使用する
このシナリオで参照セマンティクスを実現するには、次を使用できます。 std::reference_wrapper:
std::thread newThread(session, &sock, std::ref(logger));
std::ref は、参照を std::thread にコピー可能なオブジェクトとして見せる方法でラップします。ただし、基礎となるオブジェクト (この場合はロガー) の存続期間がスレッドの存続期間を超えていることを確認する必要があります。
以上がstd::thread が参照渡しの場合でもコピー コンストラクターを呼び出すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。