Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to pass contents of a vector to a thread

Tags:

c++

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
like image 383
user3816764 Avatar asked Jul 26 '14 14:07

user3816764


People also ask

Can you pass a vector as an array?

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.

Is vector thread safe in C++?

This has to be a dup. But, no, none of the standard containers are thread-safe.

Can you pass a vector by value?

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.


1 Answers

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).

like image 92
Johan Avatar answered Nov 14 '22 22:11

Johan