Reputation: 800
I have a void fun(vector<int> & v)
and I want to pass a vector to it when instantiating a thread thread t(fun, v);
. In C++14 clang 4 compilation fails, in MSVC it runs passing a copy to function.
#include <thread>
#include <vector>
#include <iostream>
using namespace std;
void fun(vector<int> & v) {
v.push_back(13);
}
int main(){
vector<int> v;
thread t(fun, v);
t.join();
cout << v.size();
}
example of gcc 5.4.0 error:
In file included from /usr/include/c++/5/thread:39:0, from source_file.cpp:1: /usr/include/c++/5/functional: In instantiation of ‘struct std::_Bind_simple))(std::vector&)>’: /usr/include/c++/5/thread:137:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::vector&); _Args = {std::vector
&}]’ source_file.cpp:12:21: required from here /usr/include/c++/5/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of))(std::vector&)>’ typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/include/c++/5/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of))(std::vector&)>’ _M_invoke(_Index_tuple<_Indices...>)
So 1) what is c++ standard stand on this issue; 2) is there a way around it (not passing a pointer and not +1 extra lambda expression as wrapper)?
Upvotes: 0
Views: 384
Reputation: 73386
As pointed out by Galik in the comment, all you need is std::ref()
:
thread t(fun, std::ref(v));
Why ?
This is because your function fun()
expects a reference to an lvalue. However when you construct your thread()
, a copy of your arguments will be passed in the new thread. Unfortunately, the compiler will not be able to instantiate the templates behind the scene with a reference to a temporary copy in this case.
Putting the std::ref()
, will cause the reference to the original to be used, and make the whole thing to work as expected.
Upvotes: 2