【发布时间】:2019-09-16 11:28:39
【问题描述】:
假设T 是一个类型,我想创建一个vector<vector<T>>。我知道最终的大小将是m x n,其中m 和n 是运行时常量。 (如果它们是编译时常量,我会使用std::array<std::array<T, n>, m>。)假设在我认真地继续我的程序之前,我有三个选择来处理我的双向量:
选项 1
std::vector<std::vector<T>> dbl_vect(m);
for (auto & v : dbl_vect)
v.reserve(n);
选项 2
std::vector<std::vector<T>> dbl_vect;
dbl_vect.reserve(m);
选项 3
std::vector<std::vector<T>> dbl_vect;
假设我不担心向量重新分配导致迭代器和引用失效,因此我们可以将其从决策过程中移除。
当然,后面的代码会有所不同,因为#1 创建了 dbl_vector 的(空)行,所以我们必须访问这些行而不是推回更多行。
选项#2 似乎没什么用,因为它不知道为每一行保留多少空间。
选项 #1 要求我通过 m 空向量的线性传递并手动调整它们的大小,但它会阻止重新分配。如果T 相当大,我相信这几乎肯定会更好,因为它可以防止复制/移动。
问题:假设T = char(或选择您最喜欢的 POD 类型)。在什么情况下我应该对选项1和3无动于衷,甚至更喜欢#3?这主要是因为char 的大小相对较小,还是因为编译器将(不)默认初始化char 的方式?如果T 更大,可能是用户定义的,我应该在什么时候开始关心(双向量的大小或T 的大小)?
Here 提出了一个有点类似的问题,关于一个向量和T=int。
【问题讨论】:
-
你想通过使用
reserve()而不是仅仅创建你想要的vectors来解决什么问题? -
@SidS 我很清楚,你的意思是一个接一个地创建它们并在我去的时候打电话给
push_back?这可能意味着重新分配,这可能值得避免。 -
@EricAuld:不,他的意思是从迭代器创建它们,以便它们从一开始就具有值。
-
@MooingDuck 哦。我假设我的代码比这更复杂,所以我不提前知道它们的值是什么。 (想象一下我正在编写代码以将所有可能的分区返回给我的情况......你明白了)
-
#4
std::vector<T> vec; vec.reserve(m * n);
标签: c++ vector dynamic-memory-allocation