Vektor von std :: threads

C ++ 11

Ich versuche eine zu machenvector vonstd::threads. Die Kombination der folgenden drei Punkte sagt, dass ich kann.

1.) Nachhttp://en.cppreference.com/w/cpp/thread/thread/thread, threadDer Standardkonstruktor von erstellt einen

Thread-Objekt, das keinen Thread darstellt.

2.) Nachhttp://en.cppreference.com/w/cpp/thread/thread/operator%3D, threadIstoperator=

Weist [dem aufrufenden Thread] mithilfe der Verschiebungssemantik den Status von [dem Parameter, bei dem es sich um eine Thread-Wertreferenz handelt] zu.

3.) Nachhttp://en.cppreference.com/w/cpp/container/vector/vectorWenn Sie nur eine Größe-Typ-Variable an einen Vektorkonstruktor übergeben, wird der Konstruktor erstellt

Der Container mit [der angegebenen Anzahl] value-initialisierten (standardmäßig für Klassen erstellten) Instanzen von T. Es werden keine Kopien erstellt.

Also habe ich das gemacht:

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

Dies läuft wie erwartet in VC11 undg ++ 4.8.0 (Online-Compiler hier) wie im folgenden zu sehen:

Konsolenausgabe:

Hello

Dann habe ich es in Clang 3.2 versucht, indem ich das Compiler-Menü auf derselben Webseite umgeschaltet habe.

stderr: 
pure virtual method called
terminate called without an active exception

Wenn ein Thread-Objekt, das einen Thread darstellt, den Gültigkeitsbereich verlässt, bevor es vorhanden istjoin()ed oderdetach()wird das Programm zum Beenden gezwungen. ich habejoin()edvecThread.at(0)Also ist das einzige, was in Frage kommt, der temporäre Thread

std::thread(foo);

in dem

vecThread.at(0) = std::thread(foo);

Zuordnung.

Gemäß der Webreferenz können Threads jedoch nur durch Verschieben einer Thread-R-Wert-Referenz zugewiesen werden. Mir fällt kein Weg dazu einjoin() oderdetach() ein temporäres Thread-Objekt.

Wenn also die Ausgabe von clang korrekt ist, wofür wird sie verwendet?threadIstoperator=? Oder ist das ein Clang-Compiler-Bug?

In g ++ 4.8.0 die Zeile ändern

vecThread.at(0) = std::thread(foo)

zu

vecThread.at(0) = std::thread{foo}

(Klammern durch geschweifte Klammern ersetzen) ergibt immer noch das erwartete ErgebnisHello Ausgabe.

Ändern Sie jedoch die Zeile aufvecThread.at(0) = {foo} macht es zu beschweren:

Beschwerde von g ++ 4.8.0 über Zahnspangen:

Fehler: Beim Konvertieren von der Initialisierungsliste in "std :: thread" wird der explizite Konstruktor "std :: thread :: thread" verwendet (_Callable &&, _Args && ...) [with _Callable = void (&) (); _Args = {}] 'vecThread.at (0) = {foo};

Das ist zu weit fortgeschritten. Ich weiß nicht, was es bedeutet.

Die gleiche Änderung im Klang zu machen, gibt dem noch Fortgeschritteneren:

Beschwerde von Clang 3.2 über Zahnspangen:

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

und ich weiß auch nicht, was das bedeutet.

Ich kann VC11 nicht verwenden, um das oben Gesagte zu bestätigen

vecThread.at(0) = {foo}

Probleme, da VC11 ab dem CTP-Compiler vom November 2012 keine einheitliche Initialisierungssyntax für die Standardbibliothek unterstützt.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage