2

我目前正在学习 C++ 中的并发性,并且遇到了使用线程向量的情况,我相信这在 C++0x 中是可能的。但是,我当前的编译器似乎没有移动感知容器的实现,因此我会因为std::thread::thread(const std::thread&)被删除而生成错误,即我只能将移动构造函数/移动赋值与std::thread.

我是否正确地认为我可以通过使用编写自定义分配器来规避这个问题

void MyAllocator::construct (pointer p, reference val)
/* should be non-const reference to val because using move constructor? */
{
    new ((void*)p) T (std::move(val));
}

而不是

void allocator::construct (pointer p, const_reference val)
{
    new ((void*)p) T (val);
}

? 或者这个主题的一些其他变体(可能使用 MyAllocator::construct 的重载)。

注意:这主要是为了作为一个短期的教育练习和足够好的执行工作来玩转容器中的线程。我只会MyAllocator在这种情况下使用。但是,也请向我指出任何可能已实现此功能的库,以便我可以在源代码上进行戳戳。

4

3 回答 3

2

解决这个问题的最简单方法是在堆上分配线程并操作指向它们的指针。

检查Boost Pointer Container图书馆:boost::ptr_vector<std::thread>在我看来你在找什么。

于 2010-09-27T14:47:23.763 回答
2

如果您的编译器不提供移动感知std::vector,那么您将不得不编写自己的专业化std::vector<std::thread>而不是仅仅提供自定义分配器。整个 C++03vector接口依赖于复制:push_back()复制元素;使用作为第二个参数传递的元素的副本resize()初始化空元素(即使这是 的默认值);, , ,并且如果向量需要重新分配,或者元素需要四处移动,则复制元素,依此类推。T()resize()reserve()insert()erase()push_back()

这是一个常见的问题,以至于我在我的(商业)just::thread实现中包含了这样一个专业化std::thread

于 2010-09-27T16:37:11.523 回答
0

std 容器只接受可复制对象的要求与 C++03 容器接口的关系比它与分配器实现的关系更大。例如

vector<T> b(100);
vector<T> a;
a=b;
assert(a==b);

该标准向我们保证 a==b 是正确的。但是,如果 T 不可复制,那么在最好的情况下 a=b 将无法编译,在最坏的情况下 a=b 是未定义的。此外,

a.push_back(T());

可能会导致 a 分配新空间,并且在引擎盖下会从旧的底层存储复制到新的底层存储。

此外,C++03 标准中没有任何内容表明实现实际上必须调用 allocator.construct,实际上很多(例如 gcc)不需要。

C++0x 标准为可移动类型的容器接口添加了新的成员函数,并阐明了诸如 operator= 之类的东西在它们存在时的行为方式。

见 www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2486.pdf

于 2010-09-27T16:00:46.510 回答