5

私は単純な c++ std::vector を持っており、その中に以下に示すようにスレッドを格納しています。コンパイル中に「does not compile」というコメントの行にエラーが表示される理由を説明してください。そして、コメント「コンパイル」のある行が機能するのはなぜですか?

#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;
 }

更新: Linux で g++ 4.4.6 を使用しています。以下はエラーです

[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
4

4 に答える 4

13

std::threadはコピーできないため、エラーが発生t、のコピーをベクターに挿入しようとしています。

これを機能させる唯一の方法は、次のことです。

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

ただし、これを行った後、tはもはやスレッドを表さないことを意味します (それが表すスレッドはベクトルに移動されました)。

于 2013-01-22T08:27:15.467 に答える
2

その理由はstd::thread、移動コンストラクターがありますが、コピー コンストラクターがないためです。

于 2013-01-22T08:28:20.563 に答える
2

これは、コピーも移動も必要としない、よりクリーンで高速なソリューションです。

workers.emplace_back(abc);
于 2013-01-22T10:20:22.310 に答える
1

はcopyablestd::threadではないため、 vector に移動できます:

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

より良い解決策は、スマート ポインターをベクターに格納することです。

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

ラムダを使用する場合、移動のみの型をキャプチャする方法がないため、回避策は移動のみの型を に格納することstd::shared_ptr<std::thread>です。

于 2013-01-22T08:28:22.083 に答える