4

After reading this thread auto&&, does it mean that we should always use auto&& instead of auto when we declare a local variable to capture the return type of a function (to exactly preserve the type returned by the function) ?

Use cases could be for instance

auto&& result = func_returning_lvalue_or_lvalue_reference();

or

auto&& iterator = vector_.begin();

or anything else.

In other terms it is normal to have a base code with a lot of auto&& ?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Guillaume Paris
  • 10,303
  • 14
  • 70
  • 145
  • [The answer](http://stackoverflow.com/a/13242177/2589776) in that thread gave enough info already. The answer will be yes if you want to accept any initializer regardless of whether it is an lvalue or rvalue expression and its constness. – herohuyongtao Apr 26 '14 at 08:45
  • @herohuyongtao: and why not using decltype(auto) instead? – Guillaume Paris Apr 26 '14 at 08:48
  • *"we should always use `auto&&`"* In C++, always do something type rules are very suspicious. [Xeo's answer](http://stackoverflow.com/a/13235843/341970) gives you good advice on using `auto&&`: "I use `auto&&` in generic code when I need a *modifyable* variable. [...]" I am voting to close this question because this also answers your question in my opinion. – Ali Apr 26 '14 at 10:42
  • Strictly speaking not an exact duplicate of [What does auto&& tell us?](http://stackoverflow.com/questions/13230480/what-does-auto-tell-us) but Xeo's answer, in my opinion, also answers this question as well. – Ali Apr 26 '14 at 10:44

2 Answers2

6

No. You should not use auto&& all the time. In particular, you shouldn't use it, if you need a copy. With auto&& you might get a copy (as a reference to a temporary object), or you might just get a reference to the original object.

For example:

auto&& name = customer.get_name(); // std::string or const std::string&
name.erase(name.find(' '));

Does this code compile? And if it compiles, does it change the name of the customer, or does it only work on a temporary object? You can't tell without looking at the signature of the function get_name().

nosid
  • 48,932
  • 13
  • 112
  • 139
4

No. It will sometimes lead to undefined behavior.

void f()
{
    string a{"a"};
    string b{"b"};
    auto&& c = move(a+b);
    ...
}

c will outlive the temporary produced by a+b. There are other ways to hit this issue also.

Todd Fleming
  • 216
  • 2
  • 4