在这段代码中,可以在返回时复制一个巨大的向量(取决于编译器):
vector<string> foo() {
vector<string> vec;
//make vec huge
return vec;
}
vector<string> bar = foo();
如何避免复制向量,而不依赖于编译器优化
现在,请理解,这只是一个简单的例子,只有一个返回语句。但是对于更复杂的情况,即使是优秀的编译器也有可能无法进行优化以避免复制向量。(这个答案在回答另一个问题时提到了一个这样的案例。)
(首先,依赖编译器优化对我来说似乎很奇怪,因为我应该编写好的、可移植的、C++代码,而不是担心这个编译器和那个编译器是如何在幕后工作的。所有这些“编译器优化”回答了其他问题,因此令我费解。)
到目前为止,我提出的一个想法是使用C++11的智能指针:
shared_ptr<vector<string>> foo() {
shared_ptr<vector<string>> vec_ptr = make_shared<vector<string>>();
//make *vec_ptr (i.e. the actual vector) huge
return vec_ptr;
}
shared_ptr<vector<string>> bar_ptr = foo();
//now, *bar_ptr is the underlying vector we can use
看起来这在任何情况下都可以避免复制。问题是,这段代码越来越麻烦了。
有什么好的、不麻烦的选择吗?据推测,C++11通过rvalue引用提供了一些新的“移动”功能。这些能帮上忙吗?
发布于 2012-12-04 13:42:30
据推测,C++11通过rvalue引用提供了一些新的“移动”功能。这些能帮上忙吗?
是的,如果编译器出于任何原因不使用RVO,那么在本例中,它将使用一个move作为std::vector有一个move操作符,当返回这样的一个变量时,它是适用的。当编译器使用c++11编译器而不作任何更改时,您的原始代码就应该这样做。
发布于 2012-12-04 13:28:37
一个古老的选项是,将向量作为对函数的引用传递,并根据需要进行更改。
void foo(vector<string> &vec){
...
foo(bar);
另一方面,正如我所理解的那样,move语义应该做您想做的事情,它可能会发生,而不会对您的代码进行任何更改,您可以通过使用调试器来检查它,让我进一步阅读。
编辑:这个问题似乎表明您的原始代码应该作为移动操作自动工作。这篇文章似乎有更多的信息,但我有点昏昏欲睡,无法掌握一切。
https://stackoverflow.com/questions/13703800
复制相似问题