What is the cause of the vector push_back error

I have a simple C ++ std :: vector and inside it I save streams as shown below. Could you explain why the line with the comment "does not compile" shows an error at compile time? And why does the comment compilation line work?

#include<thread>
#include<vector>

using namespace std;
void abc() {}
int main()
{
   vector<thread> workers;
   workers.push_back(thread(abc)); // compiles
   thread t(abc);
   workers.push_back(t); // does not compile

   return 0;
 }

UPDATE: I am using g ++ 4.4.6 for linux. Below is the error

[jim@cola c++]$ g++ -std=c++0x -pthread -g -Wall t.cpp -o t
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/x86_64-redhat-linux/bits/c++allocator.h:34,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/allocator.h:48,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/string:43,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/locale_classes.h:42,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/ios_base.h:43,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ios:43,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ostream:40,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/iostream:40,
                 from t.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::thread]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:737:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::thread, _Alloc = std::allocator<std::thread>]’
t.cpp:29:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread:122: error: deleted function ‘std::thread::thread(const std::thread&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ext/new_allocator.h:105: error: used here
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/vector:69,
                 from t.cpp:4:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = const std::thread&, _Tp = std::thread, _Alloc = std::allocator<std::thread>]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:741:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::thread, _Alloc = std::allocator<std::thread>]’
t.cpp:29:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread:122: error: deleted function ‘std::thread::thread(const std::thread&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc:314: error: used here
+5
source share
4 answers

You get an error because it std::threadcannot be copied, and you are trying to paste a copy tinto a vector.

The only way to do this work:

workers.push_back(std::move(t));

However, this would mean that after you do this, it tno longer represents the stream (the stream that it represented was moved to a vector).

+13

, , :

workers.emplace_back(abc);
+2

The reason is that it std::threadhas a move constructor but does not have a copy constructor.

+1
source

Since it is std::threadnot copied , you can transfer it to a vector:

   thread t(abc);
   workers.push_back(std::move(t));  

The best solution is to store a smart pointer in a vector:

std::vector<std::shared_ptr<std::thread>> workers;

Since when working with a lambda it is impossible to fix only the type of movement, a workaround is to save the type of movement only in std::shared_ptr<std::thread>.

+1
source

All Articles