2013-03-16 12 views
13

C++ 11Vektor von std :: fädelt

Ich versuche, ein vector von std::thread s zu machen. Die Kombination der folgenden drei Punkte sagt, dass ich kann.

1.) Nach http://en.cppreference.com/w/cpp/thread/thread/thread, thread 's schafft Standardkonstruktors ein

thread object which does not represent a thread.

2.) http://en.cppreference.com/w/cpp/thread/thread/operator%3D Laut, thread' s operator=

Assigns the state of [the parameter, which is a thread rvalue reference] to [the calling thread] using move semantics.

3.) Nach http://en.cppreference.com/w/cpp/container/vector/vector, übergibt nur eine Größe-Typ-Variable zu einem Vektorkonstruktor wird constru ct

the container with [the specified number of] value-initialized (default constructed, for classes) instances of T. No copies are made.

So habe ich dies:

#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 als in VC11 und g++ 4.8.0 (online compiler here) erwartet läuft, wie im folgenden zu sehen:

Konsolenausgabe:

Hello 

Dann versuchte ich es in Klirren 3.2, indem Sie auf derselben Webseite des Compiler-Menü Makeln, das gibt:

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

Wenn ein Thread-Objekt-die a-Thread geht repräsentiert den Gültigkeitsbereich vor join() ed oder detach() sein ed, wird das Programm gezwungen zu beenden. Ich habe join() ed vecThread.at(0), so das einzige, was in Frage bleibt, ist der temporäre Faden

std::thread(foo);

im

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

Zuordnung.

Gemäß der Webreferenz können Threads jedoch nur durch Verschieben einer Thread-rvalue-Referenz zugewiesen werden. Ich kann mir keinen Weg zu join() oder detach() ein temporäres Thread-Objekt vorstellen.

Wenn also die Ausgabe von clang korrekt ist, was ist dann thread 's operator=? Oder ist das ein Compiler-Bug?

In g ++ 4.8.0, wird die Linie

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

zu

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

(Ersetzen Klammern mit Klammern) noch ändert gibt die erwartete Hello ausgegeben.

Allerdings macht die Linie zu vecThread.at(0) = {foo} ändert es sich beschweren:

g ++ 4.8.0 Beschwerde auf Klammern:

error: converting to 'std::thread' from initializer list would use explicit constructor 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(); _Args = {}]' vecThread.at(0) = {foo};

was zu vorgerückt-ich weiß nicht, was es bedeutet.

die gleiche Änderung in Klirren zu machen gibt die noch anspruchsvollere:

Beschwerde des Klirren 3.2 auf Klammern:

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ß nicht, was das bedeutet auch nicht.

Ich kann nicht VC11 verwende die oben

vecThread.at(0) = {foo}

Probleme zu erhärten, weil VC11, wie der Compiler November 2012 CTP, nicht einheitliche Initialisierung Syntax auf dem Standard Library unterstützt.

+0

Haben Sie mit '-pthread' kompiliert? Der Code sieht gut aus, wenn auch etwas ausführlich. –

+0

Meinst du, ich sollte "-pthread" zum 'Compiler/Interpreter' Argumente Textfeld des Online-Compilers hinzufügen? Ich fügte es den originalen Compiler-/Interpreter-Argumenten der Webseite hinzu, so dass es "-std = C++ 11 -Wall -pedantisch -O2-pthread" auf clang gab, aber die gleichen Ergebnisse mit dem 'terminate' erlangte . – CodeBricks

+0

Nun, [dieser Code] (http://ideone.com/4B2Elt) funktioniert für mich, wenn kompiliert mit '-std = C++ 0x -pthread' ... –

Antwort

7

Ihr erstes Beispiel ist korrekt. Eine Exception zu werfen ist eine bekannte bug, wenn Sie clang mit libstdC++ verwenden. Um es zu lösen, müssen Sie libC++ (llvm-Version der C++ - Bibliothek) installieren. Sehen Sie ein Beispiel mit libc kompilieren ++ unter

#include <thread> 

int main() 
{ 
    std::thread t([]() {}); 
    t.join(); 
    return 0; 
} 

$ clang++ -std=c++11 -stdlib=libc++ main.cpp -o main -lc++ -lsupc++ -lpthread

P. S. Siehe here, warum wird auch die Flagge -lsupc++ benötigt.