显而易见的答案是正确的,并且基本上是最优的。
void do_stufF(std::vector<int>& on_this); // (1)
std::vector<int> do_stuff_better() { // (2)
std::vector<int> myVector_temp; // (3)
do_stuff(myVector_temp); // (4)
return myVector_temp; // (5)
}
在(3)处,我们在自动存储(在堆栈上)中创建一个命名的返回值。
在(5)处,我们只从函数返回命名的返回值,并且除了函数中其他任何地方的命名返回值之外,我们从不返回任何其他内容。
由于(3)和(5),允许编译器(并且很可能会)忽略myVector_temp
对象的存在。它将直接构造函数的返回值,并调用它 myVector_temp
。它仍然需要有一个现有的移动或复制构造函数,但它不会调用它。
另一方面,在调用 时do_stuff_better
,一些编译器也可以省略调用时的赋值:
std::vector<int> bob = do_stuff_better(); // (6)
允许编译器有效地传递一个“指向 bob 的指针”并告诉do_stuff_better()
在bob
' 的位置构造它的返回值,同时省略这个复制构造(好吧,它可以安排调用如何发生,以便do_stuff_better()
要求构造的位置它的返回值与 ) 的位置相同bob
。
在 C++11 中,即使两个省略的要求都没有得到满足,或者编译器选择不使用它们,在这两种情况下都move
必须使用 a 而不是 a copy
。
在第(5)行,我们以简单明了的return
语句返回本地声明的自动存储持续时间变量。move
如果没有省略,这使得返回是隐式的。
在第(6)行,函数返回一个未命名的对象,它是一个右值。当bob
由它构造时,它- 构造move
。
move
ing astd::vector
包括复制〜3个指针的值,然后将源归零,无论它有多大vector
。无需复制或移动任何元素。
上述两种省略,即我们在 中删除命名的局部变量do_stuff_better()
,并删除 的return
值do_stuff_better()
并直接构造bob
,都有些脆弱。学习允许编译器执行这些省略的规则以及编译器实际执行省略的情况是值得的。
作为一个脆弱的例子,如果你有一个分支,你在检查错误状态后做了一个return std::vector<int>()
,do_stuff_better()
那么函数内省略可能会被阻止。
即使省略被阻止或者你的编译器没有为一个案例实现它,容器是move
'd 的事实意味着运行时间成本将是最小的。