声明哪种类型以避免复制并确保返回的值已移动 [英] Which type to declare to avoid copy and make sure returned value is moved
问题描述
假设
- 我有一个函数
A f()
; - 我想将局部变量
a
初始化为f
的返回值; - 我不想依靠RVO;
- I have a function
A f()
; - I want to initialize a local variable
a
to the return value off
; - I don't want to rely on RVO;
什么是最佳选择(以及为什么),以避免在复制f
的返回值时
What is the best option (and why) to avoid the return value of f
being copied when
-
a
可能需要修改 - 我知道
a
不会被修改
a
may have to be modified- I know that
a
will not be modified
选项:
a)A a = f();
b)A&& a = f();
c)const A& = f();
d)const A&& = f();
a) A a = f();
b) A&& a = f();
c) const A& = f();
d) const A&& = f();
我会说:
- b)
- c)
因为两者都使用了引用,并且避免了多余的副本(RVO也可以避免,但这不能保证).那么我怎么会在大多数时间看到选项a)的建议?
Because both use references and avoid an extra copy (which could be avoided by RVO as well, but that is not guaranteed). So how come I see option a) suggested most of the time?
我想问题的核心是:我知道a)最有可能与c)具有相同的作用,那么为什么不使用c)而不是a)来使事情变得明确且独立于编译器?
I guess the heart of the question is: I get that a) most likely has the same effect as c), so why not use c) instead of a), to make things explicit and independent on the compiler?
推荐答案
那么我怎么总是看到选项a)的大部分建议?
So how come I see option a) suggested most of the time?
因为所有4个选项都以完全相同的方式返回值.唯一改变的是将变量绑定到返回的临时文件的方式.
Because all 4 options return the value the exact same way. The only thing that changes is the way you bind a variable to the returned temporary.
- a)声明类型为
A
的变量a
并将其从临时目录移动初始化.这不是分配,这是初始化.只要您没有明确禁止移动构造器,它就会被任何流行的编译器所省略,这意味着该程序将仅确保为返回值保留的存储空间是a
变量的存储空间. - c)声明变量
a
,它是对临时变量的const引用,从而延长了临时变量的生存期.这意味着临时返回值将得到存储,并且变量a
将引用该临时返回值.编译器在静态地知道引用指向返回值的情况下,将有效地生成与a)相同的代码. - b)和d),我不太确定它们有什么用. (即使该方法可行)目前我不会接受右值引用.如果需要,我以后会明确地
std::move
变量.
- a) Declares a variable
a
of typeA
and move-initializes it from the temporary. This is not an assignment, this is initialization. The move constructor will be elided by any popular compiler, provided that you don't explicitly disallow it, which means that the program will just ensure that the storage reserved for the return value is the storage for thea
variable. - c) Declares a variable
a
which is a const-reference to the temporary, extending the lifetime of the temporary. Which means that the temporary return value gets storage, and the variablea
will refer to it. The compiler, knowing statically that the reference points to the returned value, will effectively generate the same code as a). - b) and d), I am not really sure what they're good for. (and even if that works) I would not take an rvalue reference at this point. If I need one, I would explicitly
std::move
the variable later.
现在:
a可能需要修改
a may have to be modified
如果可以修改a
,请使用:
If a
may be modified, use :
auto a = f();
我知道a不会被修改
I know that a will not be modified
如果您知道不会修改a
,请使用:
If you know that a
will not be modified, use :
const auto a = f();
使用auto
将防止任何类型的不匹配. (因此,如果f
发生的任何隐式转换为A
毕竟都不会返回类型A
.哦,那些维护者...)
The use of auto
will prevent any type mismatch. (and as such, any implicit conversion to A
if f
happens not to return type A
after all. Oh, those maintainers...)
这篇关于声明哪种类型以避免复制并确保返回的值已移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!