2013-03-16 21 views
13

C++ 11wektor std :: podaje

usiłuję zrobić z std::threadvector s. Połączenie trzech następujących punktów mówi, że mogę.

1.) Według http://en.cppreference.com/w/cpp/thread/thread/thread, thread 's domyślny konstruktor tworzy

thread object which does not represent a thread.

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

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

3.) Według http://en.cppreference.com/w/cpp/container/vector/vector, przekazując tylko zmienną typu rozmiaru do konstruktora wektorowego będzie konstruować ct

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

Tak, zrobiłem to:

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

To działa zgodnie z oczekiwaniami w VC11 i g++ 4.8.0 (online compiler here) jak widać na poniższym:

konsoli wyjściowa:

Hello 

Potem próbowałem go w Clang 3.2, przełączając menu kompilatora na tej samej stronie, co daje:

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

Kiedy nitki obiektowo, który reprezentuje wątku wychodzi z zakresu zanim będzie join() ed lub detach() ed, program zostanie zmuszony do zakończenia. Mam join() ed vecThread.at(0), więc jedyne, co pozostaje w pytaniu jest tymczasowy wątek

std::thread(foo);

przypisanie

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

.

Jednak zgodnie z odniesieniem do strony internetowej wątki można przypisywać tylko przenosząc wartość rinutu wątku. Nie mogę myśleć o żadnym sposobie, aby tymczasowy obiekt wątku był .

Jeśli więc wynik działania klang jest prawidłowy, to jaki jest pożytek z ? Czy jest to błąd kompilatora clang?

In g ++ 4.8.0, zmieniając linię

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

do

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

(zastępując nawiasy szelki) wciąż daje oczekiwany Hello wyjściowe.

Jednakże, zmieniając linię vecThread.at(0) = {foo} sprawia, że ​​skarżą się:

g ++ 4.8.0 skarga na szelki na:

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

który jest zbyt zaawansowany, nie wiem co to znaczy.

Making taką samą zmianę brzękiem daje jeszcze bardziej zaawansowane: skargi

Clang 3.2 w sprawie szelek:

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 

i nie wiem, co to znaczy albo.

Nie mogę korzystać VC11 się potwierdzać powyższe

vecThread.at(0) = {foo}

problemy, ponieważ VC11, począwszy od listopada 2012 CTP kompilatora, nie umożliwia równomierne inicjalizacji składni na bibliotece standardowej.

+0

Czy kompilowałeś z '-pthread'? Kod wygląda dobrze, choć trochę gadatliwie. –

+0

Czy masz na myśli, że powinienem dodać '-pthread' do pola tekstowego' compiler/interpreter' kompilatora online? Dodałem go do oryginalnych argumentów kompilatora/interpretera w tekście strony, czyniąc go '-std = C++ 11 -Wall-W -pedantic -O2 -pthread' na clang, ale otrzymałem te same wyniki z wywołaniem' terminate' . – CodeBricks

+0

Cóż, [ten kod] (http://ideone.com/4B2Elt) działa dla mnie po skompilowaniu z '-std = C++ 0x -pthread' ... –

Odpowiedz

7

Twój pierwszy przykład jest poprawny. Zgłaszanie wyjątku jest znane pod numerem bug, gdy używasz języka clang z libstdC++. Aby go rozwiązać, musisz zainstalować bibliotekę libC++ (biblioteka llvm w wersji C++). Zobacz przykład kompilacji z libC++ poniżej

#include <thread> 

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

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

PS: Zobacz here, dlaczego wymagana jest również flaga -lsupc++.

Powiązane problemy