繁体   English   中英

按值返回std :: vector

[英]Returning std::vector by value

人们常说,在C ++ 11中,按值返回std::vector是理智的。

在C ++ 03中,这主要是正确的,因为RVO应该优化副本。 但这应该让大多数开发人员感到害怕。

  • 在C ++ 11中,返回的std::vector局部变量总会被移动吗?
  • 如果该向量是局部变量的成员而不是局部变量本身怎么办?
  • 显然,不会移动返回全局变量。 还有什么其他案例不会被移动?

首先,每次复制之前都可以省略,现在仍然可以省略,并且可以在相同的情况下省略移动。 对于这篇文章的其余部分,我将假设elision不会因某种原因发生(假装编译器编写者以一种糟糕的方式懒惰)。

在C ++ 11中,返回的std :: vector局部变量总会被移动吗?

每次满足复制省略的标准,或者变量显式为std::move d。

如果该向量是局部变量的成员而不是局部变量本身怎么办?

除非显式std::move d,否则不会移动它。

显然,不会移动返回全局变量。 还有什么其他案例不会被移动?

每次不满足复制省略的标准,并且变量不是明确的std::move d。

这些都不是不按价值返回的正当理由。 按值返回是正常的,因为即使没有自动移动值,您也可以使用std::move强制它。

在C ++ 11中,返回的std::vector局部变量总会被移动吗?

对于局部变量,甚至是按值参数,编译器必须始终首先尝试移动它(如果移动和副本都不能因任何原因而被删除,即使满足条件)。 如果失败,它会再次尝试使用副本:

§12.8 [class.copy] p32

当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实, 并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的 如果重载决策失败,或者所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv-qualified),则再次执行重载决策,将对象视为左值。 [ 注意:无论是否发生复制省略,都必须执行此两阶段重载决策。 如果未执行elision,它将确定要调用的构造函数,并且即使调用被省略,也必须可以访问所选的构造函数。 - 尾注 ]

如果该向量是局部变量的成员而不是局部变量本身怎么办?

不会尝试移动子对象,因为它不符合复制省略的标准。 (这是愚蠢的,恕我直言,但这就是目前的情况。我不认为这两者应该联系起来,因为如果它是本地的,那么子对象可以完全被移动。)

显然,不会移动返回全局变量。 还有什么其他案例不会被移动?

显然不会移动引用。 除此之外,我无法想到其他任何事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM