15

C++11

我正在尝试制作一个vectorof std::threads。结合以下三点说我可以。

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

不代表线程的线程对象。

2. )根据http://en.cppreference.com/w/cpp/thread/thread/operator%3Dthreadoperator=

使用移动语义将 [参数,它是线程右值引用] 的状态分配给 [调用线程]。

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()当代表线程的线程对象在被ed 或ed之前超出范围时detach(),程序将被强制终止。我已经join()编辑vecThread.at(0)了,所以唯一剩下的就是临时线程

std::thread(foo);

在里面

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

任务。

但是,根据网络参考,线程只能通过移动线程右值引用来分配。我想不出任何方法join()detach()临时线程对象。

所以如果 clang 的输出是正确的,那么thread's有什么用operator=呢?或者这是一个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,截至 2012 年 11 月的 CTP 编译器,不支持标准库上的统一初始化语法。

4

1 回答 1

8

你的第一个例子是正确的。当您将 clang 与 libstdc++ 一起使用时,抛出异常是一个已知错误。要解决它,您必须安装 libc++(llvm 版本的 c++ 库)。请参阅下面的使用 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

PS看到这里,为什么也-lsupc++需要标志。

于 2013-03-16T06:49:56.907 回答