2015-12-03 29 views
14

std::threadを作成するときに参照でオブジェクトを渡すことができないのはなぜですか?例えばC++のstd :: threadへの参照でオブジェクトを渡す11

には、以下のsnippitは、コンパイルエラーを与える:

#include <iostream> 
#include <thread> 

using namespace std; 

static void SimpleThread(int& a) // compile error 
//static void SimpleThread(int a)  // OK 
{ 
    cout << __PRETTY_FUNCTION__ << ":" << a << endl; 
} 

int main() 
{ 
    int a = 6; 

    auto thread1 = std::thread(SimpleThread, a); 

    thread1.join(); 
    return 0; 
} 

エラー:

In file included from /usr/include/c++/4.8/thread:39:0, 
       from ./std_thread_refs.cpp:5: 
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<void (*(int))(int&)>’: 
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int&); _Args = {int&}]’ 
./std_thread_refs.cpp:19:47: required from here 
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<void (*(int))(int&)>’ 
     typedef typename result_of<_Callable(_Args...)>::type result_type; 
                  ^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<void (*(int))(int&)>’ 
     _M_invoke(_Index_tuple<_Indices...>) 
     ^

私はポインタを渡すに変更しましたが、より良い仕事が周りにあるのでしょうか?

答えて

25

明示reference_wrapper by using std::refでスレッドを初期化:

auto thread1 = std::thread(SimpleThread, std::ref(a)); 

(代わりstd::refまたはstd::crefを、必要に応じて)。 cppreference on std:threadからノートパー:スレッドがそれを読むことができる前にパラメータが去って行った場合はそれ以外のものは恐ろしく失敗するので

The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).

+8

キャプチャ、賢明に、デフォルト値でキャプチャします。この動作を明示的に求めて、参照のターゲットが依然として有効であることを保証する責任を負っていることを示す必要があるようにする必要があります。 –

+0

優秀!私は、明示的に参照を渡す方法があることを望んでいました。再び救助へのC++ 11 :) – austinmarton

関連する問題