为什么std :: vector fill构造函数不能启用安置?

时间:2014-10-30 18:10:23

标签: c++11 vector move-semantics

当我需要创建一个非可复制构造对象的数组时,我偶尔会遇到这种情况。例如:

std::vector<std::thread> thread_pool(NUM_CORES, std::thread(some_function));

这很方便。但是,std::vector填充构造函数似乎没有任何R值支持。它被定义为:

 vector( 
         size_type count, 
         const T& value,
         const Allocator& alloc = Allocator()
 );

但是非常方便

 vector( 
         size_type count, 
         T&& value,
         const Allocator& alloc = Allocator()
 );

然后,向量可以在内部分配必要的缓冲区大小,并使用placement new移动构造每个元素。

但是...... C ++ 11标准(显然甚至是C ++ 14标准)都没有提供这种功能。所以,现在 - 当我有一个线程向量时,我不得不说:

std::vector<std::unique_ptr<std::thread>> thread_pool(NUM_CORES);
/* now loop over vector and initialize elements one by one */

是否有某种原因忽略了这种能力?有危险吗?还是我看不到的一些问题?

1 个答案:

答案 0 :(得分:5)

你提出的建议是不可行的,因为从本质上来说,移动是一种状态从一个对象转移到一个其他宾语。你不能通过同时将状态从一个移动到所有对象来构造 N 对象。

星际之门的宇宙违反了这一规则,引入了同时向星系中的每个门打开虫洞的能力,这根本没有任何意义,真让我烦恼。不要那个人!

一个矢量构造函数,如下所示:

template <typename T>
template <typename Args...>
std::vector<T>::vector(const size_t n, Args&&... args);

...跟随emplace模型可以工作,但我担心由于std::vector<T>的现有构造函数的数量很多,很容易导致模糊的重载。我怀疑这是为什么它没有完成,除了它不是真的必要的事实。

因为,现在,您可以通过一次安装一个来解决它,无论如何,这可能是您希望得到的高效性:

std::vector<std::thread> v;
v.reserve(NUM_CORES);
for ( /*...*/ )
   v.emplace_back( /*...*/ );