Search code examples
c++c++11autouniversal-reference

When not to use `auto&&`?


  auto&& mytup = std::make_tuple(9,1,"hello");
  std::get<0>(mytup) = 42;
  cout << std::get<0>(mytup) << endl;
  1. Is there a copy/move involved (without RVO) when returning from make_tuple?
  2. Is it causing undefined behavior?
  3. I can both read write the universal reference. Can auto&& var = func() be used always instead of auto var = func() so that there is no copy/move?

Solution

    1. Yes. Any return from a function that does not return a reference type may involve a copy/move. Eliding that is what RVO is about. The object that your reference is bound to needs to be initialized somehow.

    2. No. why should it? The lifetime of a temporary/prvalue bound to a reference is determined by the scope of the reference.

    3. If func() does not return a reference type, there should not be any difference in efficiency (nor behaviour)

    between

    auto&& var = func();
    

    and

    auto var = func();
    

    In both cases an object with lifetime to the end of the containing block is constructed. In one case it has its own name, in the other it is named via a reference. In both cases the name can be used as an lvalue. RVO can be equally well applied in either case.

    Some compilers might optimize better for a local object than for a reference, even though in the current case the reference-to-temporary is really no different from a local object.

    If func() might return a reference, things are much different - in that case you must decide whether you want to copy/move or not.