2

我有一个很简单的问题:当我们使用向量std::vector<int>作为函数的参考参数时,我们应该在调用函数之前调整向量的大小还是在函数内部调整向量的大小(假设向量的大小可以事先确定?我举以下例子来说明我的问题:

void fun1(std::vector<int> &para)
{
  para[0] = 1;
  para[1] = 2;
  ....
  para[10] = 11;

}
void fun2(std::vector<int> &para)
{
  para.resize(11);
  para[0] = 1;
  para[1] = 2;
  ...
  para[10] = 11;
}

当我们调用 fun1 时,我们使用以下代码:

std::vector<int> mypara;
mypara.resize(11);
fun1(mypara);

当我们调用 fun2 时,我们使用以下代码:

std::vector<int> mypara;
fun2(mypara);
4

6 回答 6

3

...您可能应该只返回向量。

std::vector<int> fun3()
{
  std::vector<int> para(11);
  para[0] = 1;
  para[1] = 2;
  ...
  para[10] = 11;
  return para;
}

我知道这感觉不对,但 C++/STL 实际上对这类事情非常聪明。它实际上不会复制出 para,它将执行移动构造函数/执行返回值优化,而不是复制构造函数。

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

于 2013-05-29T13:35:52.560 回答
3

只需使用 push_back 并在必要时让向量自行调整大小:

std::vector<int> mypara;
mypara.push_back(1);
...
mypara.push_back(11);

如果您知道有多少元素适合您的向量,您可以reserve在添加元素或将初始大小设置为参数之前调用:

std::vector<int> mypara(10);//Be aware that this will create 10 elements!
//or...
std::vector<int> mypara;
mypara.reserve(10);//This will set the size, but there won't be any elements in it yet.

向量的初始大小对于大多数情况来说足够大,并且不会经常调整大小。但有时当您仅添加一个元素并将其调整为更大的尺寸时,有时会导致问题。在这种情况下,使用储备也可以提高性能。

但是,如果您必须调整大小,请根据您的情况在函数中进行。代码的读者更清楚,可以看出你的意图。保持范围小。

于 2013-05-29T13:28:55.223 回答
3

您通常根本不会显式地resize使用向量——无论是在函数调用中还是在调用函数之前。 vector管理自己的内存使用,并根据需要增长以适应新元素。

在某些情况下,您将添加鬃毛元素并且不希望出于性能原因而多次重新分配矢量。这通常只会发生在您的应用程序的“热路径”中,而不是针对每个应用程序。在这些相对少见的场景中,添加元素的函数应该负责确保向量中有足够的容量。为此,您不要使用resize,而是使用reserve。两者都会重新分配vectorif necesarry (并因此使迭代器无效,所以要小心),但resize实际上改变了size()capacity()vectorreserve只改变了capacity().

要了解区别:

vector <int> v;
v.reserve (10);
copy (v.begin(), v.end(), ostream_iterator (cout, ","));

上面的内容不会输出任何内容,因为 中没有任何内容vector,即使有 10 个元素的空间。然而:

vector <int> v;
v.resize (10);
copy (v.begin(), v.end(), ostream_iterator (cout, ","));

此代码将输出 10 个默认构造int的 s。数组中有 10 个元素。如果你是resizing()一个vector单纯为新元素腾出空间的人,resize()可能不是你想做的。

于 2013-05-29T13:39:50.300 回答
2

两者都是正确的,尽管 fun2 似乎更安全一些。您可以将它复制到另一个项目,它会工作得很好,而不是 fun1 需要事先正确调整 para 的大小。

于 2013-05-29T13:30:11.463 回答
1

i think if u can know at run time what would be the size you require now , you should call resize . Why ? as this will prevent the overhead of multiple time of size increase and copying ...

So answer is .. at the moment in your function when you know that a large chunk of insertion are going to happen , so you would like to do it at once ...

于 2013-05-29T13:37:55.223 回答
1

如果您的函数对输入向量有要求,不使用其数据,并假设它是可覆盖的,那么最好简单地按值返回向量:

std::vector<int> fun()
{
  std::vector<int> v(11);
  std::iota(v.begin(), v.end(), 1);
  return v;
}

这样,调用者不必担心输入向量的状态,函数也不必对向量进行任何检查。

于 2013-05-29T13:36:56.310 回答