Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 506
balki Avatar asked Feb 13 '13 08:02

balki


1 Answers

It's only ever problematic in the case where the initializer is a function call that returns a short-lived rvalue reference. With less words and more code:

// Fine; lifetime extension applies!
auto&& ref = 42;

auto id = [](int&& i) -> int&& { return std::move(i); };
auto&& uhoh = id(42);
// uhoh is now a stale reference; can't touch it!

In contrast, auto uhoh = id(42); would have worked fine.

In your case, because std::make_tuple returns a value and not an rvalue reference there is no problem.

I'm of the opinion that the real danger is from those functions and function templates with rvalue reference parameters and that return an rvalue reference to either those of some subobjects which lifetimes depend on those. (That being said, something as simple as auto&& ref = std::move(42); exhibits the problem!)

The situation is not entirely new from C++11, consider: T const& ref = bar(T_factory());.

like image 56
Luc Danton Avatar answered Sep 30 '22 03:09

Luc Danton