假设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
。
如果你知道内部大小将是m
,一种可能性是制作一个std::vector<S>
,其中S
是你的自定义类型代表std::vector<T>
,除了它知道它将有多少条目。建议使用类似的解决方案here(除了m
是编译时常量)。
#3只是默认 - 初始化向量。你没有从中获得任何东西,因为包含向量的容量为零。动态分配内存很慢,所以为了最小化这个,我总是使用#1或其变体。