如何构造非默认可构造对象的std :: vector?

时间:2013-08-22 14:09:29

标签: c++ c++11

我从C++ reference page发现了这样的代码:

#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以这种方式初始化操作系统新给你的一块内存?

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

3 个答案:

答案 0 :(得分:6)

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

例如,以下内容不起作用:

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

答案 1 :(得分:2)

std::vector<>的构造函数首先获取一个适当大小的原始内存块(使用其allocator)。然后它构造对象。如果是特定的构造函数

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

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

答案 2 :(得分:1)

向量中的所有对象都是使用一个带有int的参数构造函数构造的。这就是为什么你不需要语义上的默认构造函数。

就实现而言,可以通过使用malloc而不是new分配内存来实现此行为(因此不会调用构造函数),然后使用展示位置new将元素添加到向量时。