Which type to declare to avoid copy and make sure

2019-04-02 23:39发布

Suppose that

  • 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;

What is the best option (and why) to avoid the return value of f being copied when

  1. a may have to be modified
  2. I know that a will not be modified

Options:

a) A a = f(); b) A&& a = f(); c) const A& = f(); d) const A&& = f();


EDIT:

I would say:

  1. b)
  2. c)

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?

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?

2条回答
倾城 Initia
2楼-- · 2019-04-03 00:21

So how come I see option a) suggested most of the time?

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) 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.

Now :

a may have to be modified

If a may be modified, use :

auto a = f();

I know that a will not be modified

If you know that a will not be modified, use :

const auto a = f();

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...)

查看更多
萌系小妹纸
3楼-- · 2019-04-03 00:29

If class A have move-constructor then just use A a = f(); If you know nothing about class A you can rely only on RVO or NRVO optimization.

查看更多
登录 后发表回答