std::线程的矢量

vector of std::threads

本文关键字:线程 std      更新时间:2023-10-16

C++11

我正在尝试制作std::threads的vector。以下三点的结合表明我可以。

1.(根据http://en.cppreference.com/w/cpp/thread/thread/thread,thread的默认构造函数创建一个

不表示线程的线程对象。

2.(根据http://en.cppreference.com/w/cpp/thread/thread/operator%3D,threadoperator=

指定[参数的状态是使用move对[调用线程]的线程右值引用语义。

3.(根据http://en.cppreference.com/w/cpp/container/vector/vector,通过只有向量构造函数的大小类型变量才能构造

初始化了[指定数量]值的容器(默认构造,用于类(的实例。不进行复制。

所以,我这样做了:

#include <iostream>
#include <thread>
#include <vector>
void foo()
{
    std::cout << "Hellon";
    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() ed或detach() ed之前超出作用域时,程序将被迫终止。我有join()vecThread.at(0),所以唯一有问题的是临时线程

std::thread(foo);

在中

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

任务。

但是,根据web引用,只能通过移动线程值引用来分配线程。我想不出任何方法可以将join()detach()作为临时线程对象。

那么,如果clang的输出是正确的,那么threadoperator=有什么用呢?或者这是一个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&&amp;,_Args&&amp;…([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}

问题,因为自2012年11月起,VC11的CTP编译器不支持标准库上的统一初始化语法。

您的第一个示例是正确的。当您将clang与libstdc++一起使用时,引发异常是一个已知的错误。要解决这个问题,您必须安装libc++(c++库的llvm版本(。请参阅下面的使用libc++编译的示例

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

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

附言:请看这里,为什么也需要标志-lsupc++