C ++ 11
私はsを作ろうとしていvector
ますstd::thread
。次の3つのポイントの組み合わせは私ができると言います。
1.) http://en.cppreference.com/w/cpp/thread/thread/threadによると、
thread
のデフォルトコンストラクタは
スレッドを表さないスレッドオブジェクト。
2.) http://en.cppreference.com/w/cpp/thread/thread/operator%3Dによるthread
と、operator=
移動セマンティクスを使用して、[スレッドの右辺値参照であるパラメーター]の状態を[呼び出し元のスレッド]に割り当てます。
3.) http://en.cppreference.com/w/cpp/container/vector/vectorによると 、サイズ型変数のみをベクトルコンストラクターに渡すと次のようになります。
[指定された数]の値が初期化された(クラスの場合はデフォルトで構築された)インスタンスを持つコンテナー。コピーは作成されません。
だから、私はこれをしました:
#include <iostream>
#include <thread>
#include <vector>
void foo()
{
std::cout << "Hello\n";
return;
}
int main()
{
std::vector<std::thread> vecThread(1);
vecThread.at(0) = std::thread(foo);
vecThread.at(0).join();
return 0;
}
これは、以下に示すように、VC11およびg ++ 4.8.0(ここではオンラインコンパイラ)で期待どおりに実行されます。
コンソール出力:
Hello
次に、同じWebページでコンパイラメニューを切り替えて、clang3.2で試してみました。
stderr:
pure virtual method called
terminate called without an active exception
スレッドを表すスレッドオブジェクトがjoin()
edまたはdetach()
edされる前にスコープ外になると、プログラムは強制的に終了します。私はjoin()
編集vecThread.at(0)
したので、問題になっているのは一時的なスレッドだけです
std::thread(foo);
の中に
vecThread.at(0) = std::thread(foo);
割り当て。
ただし、Web参照によると、スレッドはスレッド右辺値参照を移動することによってのみ割り当てることができます。join()
一時的detach()
なスレッドオブジェクトへの道は考えられません。
それで、clangの出力が正しい場合、thread
'sの使用は何operator=
ですか?それとも、これはclangコンパイラのバグですか?
g ++ 4.8.0では、行を変更します
vecThread.at(0) = std::thread(foo)
に
vecThread.at(0) = std::thread{foo}
(括弧を中括弧に置き換えても)期待されるHello
出力が得られます。
ただし、行を変更しvecThread.at(0) = {foo}
て文句を言うようにします。
中括弧に関するg++4.8.0の苦情:
エラー:初期化子リストから'std :: thread'に変換すると、明示的なコンストラクター' std :: thread :: thread(_Callable &&、_Args && ...)[with _Callable = void(&)(); _Args = {}]'vecThread.at(0)= {foo};
これはあまりにも進んでいます—それが何を意味するのかわかりません。
clangで同じ変更を加えると、さらに高度になります。
中括弧に関するclang3.2の苦情:
error: no viable overloaded '='
vecThread.at(0) = {foo};
...
note: candidate function not viable: cannot convert initializer list
argument to 'const std::thread'
thread& operator=(const thread&) = delete;
...
note: candidate function not viable: cannot convert initializer list
argument to 'std::thread'
thread& operator=(thread&& __t) noexcept
それが何を意味するのかもわかりません。
上記を裏付けるためにVC11を使用することはできません
vecThread.at(0) = {foo}
2012年11月のCTPコンパイラの時点でVC11は、標準ライブラリで統一された初期化構文をサポートしていないため、問題が発生します。