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

Sil*_*ler 1 vector move-semantics c++11

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

std::vector<std::thread> thread_pool(NUM_CORES, std::thread(some_function));
Run Code Online (Sandbox Code Playgroud)

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

 vector( 
         size_type count, 
         const T& value,
         const Allocator& alloc = Allocator()
 );
Run Code Online (Sandbox Code Playgroud)

但是拥有以下内容会非常方便:

 vector( 
         size_type count, 
         T&& value,
         const Allocator& alloc = Allocator()
 );
Run Code Online (Sandbox Code Playgroud)

然后向量可以在内部分配必要的缓冲区大小,并使用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 */
Run Code Online (Sandbox Code Playgroud)

有什么理由将这种能力排除在外吗?有危险吗?还是我看不到的一些问题?

Lig*_*ica 5

因为,就其本质而言,你提出什么是不可行的运动是一个国家从转移一个物体到一个其他对象.您不能通过同时将状态从一个移动到所有对象来构造N个对象.

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

一个矢量构造函数看起来像这样:

template <typename T>
template <typename Args...>
std::vector<T>::vector(const size_t n, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

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

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

std::vector<std::thread> v;
v.reserve(NUM_CORES);
for ( /*...*/ )
   v.emplace_back( /*...*/ );
Run Code Online (Sandbox Code Playgroud)