如何构造非默认可构造对象的std::向量

How is it possible to construct a std::vector of non-default constructible objects?

本文关键字:对象 std 向量 何构造 默认      更新时间:2023-10-16

我在C++参考页面上看到了这样的代码:

#include <algorithm>
#include <list>
#include <vector>
#include <functional>
int main()
{
    std::list<int> l = {-4, -3, -2, -1, 0, 1, 2, 3, 4};
    std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
    return 0;
}

这是"示例"部分的一个片段。代码按预期编译并运行。但这怎么可能呢?std::reference_wrapper<int>不是默认可构造的。你怎么能把这些东西做成std::vector?我一直把std::vector想象成一个动态数组。但是,如何从std::list初始化操作系统新提供给您的内存块呢?

这听起来可能是一个令人困惑的问题,但由于某种原因,我无法完全理解上面代码中发生了什么。里面发生了什么事?

它之所以有效,是因为那里没有默认的初始化-列表中的元素用于复制初始化向量。

例如,以下方法不起作用:

std::vector<std::reference_wrapper<int>> v(42);

std::vector<>的构造函数首先获得一个适当大小的原始内存块(使用其allocator)。然后它构造对象。在这里的特定构造函数的情况下

template<typename It>
std::vector::vector(It begin, It end);

它从迭代器的valuetype构造元素,因此每个reference_wrapper<int>都是从int构造的(就地)。

向量中的所有对象都是使用一个带int的单参数构造函数构建的。因此,在语义上不需要默认构造函数。

就实现而言,可以通过用malloc而不是new来分配内存(因此没有调用构造函数),然后在向向量添加元素时使用放置new来实现这种行为。