当我需要创建一个非可复制构造对象的数组时,我偶尔会遇到这种情况。例如:
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 */
是否有某种原因忽略了这种能力?有危险吗?还是我看不到的一些问题?
答案 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( /*...*/ );