声明哪种类型以避免复制并确保返回的值已移动 [英] Which type to declare to avoid copy and make sure returned value is moved

查看:83
本文介绍了声明哪种类型以避免复制并确保返回的值已移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设

  • 我有一个函数A f();
  • 我想将局部变量a初始化为f的返回值;
  • 我不想依靠RVO;
  • I have a function A f();
  • I want to initialize a local variable a to the return value of f;
  • 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

  1. a可能需要修改
  2. 我知道a不会被修改
  1. a may have to be modified
  2. 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();

我会说:

  1. b)
  2. 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 type A 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 the a 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 variable a 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆