вектор std :: threads

C ++ 11

Я пытаюсь сделатьvector изstd::threads. Сочетание следующих трех пунктов говорит, что я могу.

1.) Согласноhttp://en.cppreference.com/w/cpp/thread/thread/thread, threadКонструктор по умолчанию создает

объект потока, который не представляет поток.

2.) Согласноhttp://en.cppreference.com/w/cpp/thread/thread/operator%3D, thread«soperator=

Присваивает состояние [параметра, который является ссылкой на значение потока] [вызывающему потоку], используя семантику перемещения.

3.) Согласноhttp://en.cppreference.com/w/cpp/container/vector/vectorпередача только переменной типа размера в векторный конструктор

контейнер с [указанным числом] инициализированных значением (построенных по умолчанию, для классов) экземпляров T. Копии не создаются.

Итак, я сделал это:

#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

Затем я попробовал это в clang 3.2, переключая меню компилятора на той же веб-странице, что дает:

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

Когда объект потока, представляющий поток, выходит из области видимости, прежде чемjoin()ред илиdetach()Эд, программа будет вынуждена прекратить. у меня естьjoin()изданиеvecThread.at(0)Таким образом, единственное, что остается под вопросом, это временная нить

std::thread(foo);

в

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

назначение.

Однако, согласно веб-ссылке, потоки могут быть назначены только путем перемещения ссылки на значение потока. Я не могу придумать способjoin() или жеdetach() объект временного потока.

Так что, если вывод Clang правильный, то какая польза отthread«soperator=? Или это ошибка компилятора 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 дает еще более продвинутые:

жалоба clang 3.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}

проблемы, поскольку VC11, начиная с компилятора CTP, выпущенного в ноябре 2012 года, не поддерживает единый синтаксис инициализации в стандартной библиотеке.

Ответы на вопрос(1)

Ваш ответ на вопрос