I have a function that takes a vector of strings, and I have a series of those string vectors in a vector.
I wanted to loop through the vector passing each vector of strings to a new thread.
for (vector<vector<string> >::iterator it = vecstringvec.begin() ;
it != vecstringvec.end(); ++it){
threadvector.push_back(thread(func, *it));
}
Essentially the above, except the above doesn't work (compile error). What I believe is that I need a std::ref of the vector to pass along, but I'm not sure exactly, or how to do that using the iterator.
full error:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<void (*(std::vector<std::basic_string<char> >, std::reference_wrapper<std::vector<std::basic_string<char> > >))(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&); _Args = {std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::reference_wrapper<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]’
prog.cpp:199:55: required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<void (*(std::vector<std::basic_string<char> >, std::reference_wrapper<std::vector<std::basic_string<char> > >))(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&)>’
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 (*(std::vector<std::basic_string<char> >, std::reference_wrapper<std::vector<std::basic_string<char> > >))(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&)>’
_M_invoke(_Index_tuple<_Indices...>)
^
make: *** [prog.o] Error 1
Yes. Assuming v. size() > 0 , this is safe (If the vector is empty, then v[0] results in undefined behavior). The elements of a std::vector container are stored contiguously, just like in an ordinary array.
This has to be a dup. But, no, none of the standard containers are thread-safe.
Passing by value keeps the original vector unchanged and doesn't modify the original values of the vector. However, the above style of passing might also take a lot of time in cases of large vectors. So, it is a good idea to pass by reference.
Looking at the error message, func()
vector parameter is a pass-by-reference and not a pass-by-value. Try using std::ref(*it)
.
Quoting cppreference:
The arguments to the thread function are 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).
Example:
#include <vector>
#include <thread>
#include <iostream>
void func(const std::vector<int>& value)
{
std::cout << "Value: " << value.size() << std::endl;
}
int main(int argc, char const *argv[])
{
std::vector<std::vector<int>> values =
{ { 1, 2 } , { 1, 2, 3 }, { 1, 2, 3, 4 } };
std::vector<std::thread> threads;
for (auto& vect: values)
{
threads.emplace_back(func, std::cref(vect));
}
for (auto& thread: threads)
{
thread.join();
}
return 0;
}
(BTW the diagnostic would have been much easier with a full self contained example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With