Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

decltype(auto) vs auto&& to perform generic handling of function's return type

Tags:

c++

c++14

When using auto&& to handle a function returning an lvalue:

int func()
{
   int v=42;
   return v;
}

auto && v = func();

What are the consequences of treating v as a reference instead of an lvalue? Do these consequences justify the use of decltype(auto) instead of auto&& to perform generic handling of function's return type?

like image 464
Guillaume Paris Avatar asked Nov 20 '13 07:11

Guillaume Paris


People also ask

What is the difference between auto and decltype Auto?

'auto' lets you declare a variable with a particular type whereas decltype lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression.

What is the use of decltype?

The decltype type specifier yields the type of a specified expression. The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a function template whose return type depends on the types of its template arguments.

What is auto CPP?

The auto keyword is a simple way to declare a variable that has a complicated type. For example, you can use auto to declare a variable where the initialization expression involves templates, pointers to functions, or pointers to members.

Which is the default return type specifier in C Plus Plus?

I have recently read that the default return type for all functions in C++ is int .


1 Answers

auto&& is already optimal for capturing function return values, such that the differences of decltype(auto) can only be disadvantages. In your example, lifetime extension is applied to the otherwise-temporary object returned from the function. This causes it to behave essentially the same as a directly named object, with the effect that the reference qualifier gets "erased."

Using decltype(auto) with a return-by-value function causes its return value object to be moved into the local. Depending what's inside the function, copy elision may apply which removes the distinction between the local and the temporary. But that only applied sometimes, whereas reference-bound lifetime extension is unconditional.

Even when applied, copy elision doesn't remove the requirement that the return object could be copied or moved. decltype(auto) can't initialize an object of non-movable type from a function return whereas auto && can, modulo the distinction between a local and a temporary with the lifetime of a local.

As it happens, that distinction can only be made by decltype, and it can only be made outside the local scope by decltype(auto). Since you usually want to treat lifetime-extended objects as locals, it is best to mind parentheses and std::decays when using decltype, and not to use decltype(auto) for function parameters (which is the most common application of auto &&).

like image 180
Potatoswatter Avatar answered Sep 21 '22 19:09

Potatoswatter