wektor std :: thread

C ++ 11

Próbuję zrobićvector zstd::threads. Połączenie następujących trzech punktów mówi, że mogę.

1.) Wedłughttp://en.cppreference.com/w/cpp/thread/thread/thread, threadDomyślny konstruktor tworzy a

obiekt wątku, który nie reprezentuje wątku.

2.) Wedłughttp://en.cppreference.com/w/cpp/thread/thread/operator%3D, threadSoperator=

Przypisuje stan [parametru, który jest odwołaniem do wartości rvue wątku] do [wątku wywołującego] za pomocą semantyki ruchu.

3.) Wedłughttp://en.cppreference.com/w/cpp/container/vector/vector, przekazanie tylko zmiennej typu rozmiaru do konstruktora wektorowego skonstruuje

kontener z [określoną liczbą] zainicjowany wartością (domyślnie skonstruowany, dla klas) instancje T. Żadne kopie nie są wykonywane.

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 ig ++ 4.8.0 (tutaj kompilator online) jak widać poniżej:

Wyjście konsoli:

Hello

Następnie spróbowałem 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

Gdy obiekt wątku - który reprezentuje wątek - wychodzi z zakresu zanim zostaniejoin()ed lubdetach()ed, program zostanie zmuszony do zakończenia. mamjoin()wydvecThread.at(0), więc jedyną rzeczą, która pozostała pod znakiem zapytania, jest wątek tymczasowy

std::thread(foo);

w

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

zadanie.

Jednak zgodnie z odsyłaczem do strony wątki mogą być przypisane tylko przez przeniesienie odniesienia wartości rv wątku. Nie mogę wymyślić żadnego sposobujoin() lubdetach() tymczasowy obiekt wątku.

Więc jeśli wynik clang jest poprawny, to jaki jest pożytekthreadSoperator=? Czy jest to błąd kompilatora klangów?

W g ++ 4.8.0, zmiana linii

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

do

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

(zastępując nawiasy klamrami) nadal daje oczekiwaneHello wydajność.

Jednak zmiana linii navecThread.at(0) = {foo} sprawia, że ​​narzeka:

Skarga g ++ 4.8.0 na nawiasy klamrowe:

błąd: konwersja do 'std :: thread' z listy inicjalizacyjnej użyłaby jawnego konstruktora 'std :: thread :: thread (_Callable &&, _Args && ...) [z _Callable = void (&) (); _Args = {}] 'vecThread.at (0) = {foo};

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

Dokonanie tej samej zmiany w klanie daje jeszcze bardziej zaawansowanym:

skandować skargę 3.2 na szelkach:

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 oznacza.

Nie mogę użyć VC11 do potwierdzenia powyższego

vecThread.at(0) = {foo}

problemy, ponieważ VC11, od kompilatora CTP z listopada 2012 r., nie obsługuje jednolitej składni inicjalizacji w bibliotece standardowej.

questionAnswers(1)

yourAnswerToTheQuestion