What does `auto &&i = foo();` mean

c++, c++11, forwarding-reference

Solution

`auto&&` (just like `T&&` in parameter of a function template where `T` is a template parameter of that function template) follows slightly different rules than other deductions - it's unofficially called a "universal reference."

The idea is that if the initialiser is an lvalue of type `X`, the `auto` is deduced to `X&`. If it's an rvalue of type `X`, the `auto` is deduced to `X`. In both cases, `&&` is then applied normally. From reference collapsing rules, `X& &&` becomes `X&`, while `X &&` remains `X&&`.

This means that in your `a1` case, `auto` is indeed deduced to `int`, but `a1` is then naturally declared with type `int&&`, and that's what `decltype(a1)` gives you.

At the same time, the `auto` in `a2` is `float&`, and so is the type of `a2`, which the `decltype(a2)` again confirms.

In other words, your expectation that `auto -> int` in the first case is correct, but the type of `a1` is `auto &&a1`, not just `auto a1`.

Problem

Please explain how auto type deduction works when used with move semantic: ``` #include <iostream> template <typename T> struct A { static void type() { std::cout << __PRETTY_FUNCTION__ << std::endl; } }; float& bar() { static float t = 5.5; return t; } int foo() { return 5; } int main() { auto &&a1 = foo(); // I expected auto -> int (wrong) auto &&a2 = bar(); // I expected auto -> float& (correct) A<decltype(a1)>::type(); A<decltype(a2)>::type(); } ``` The output is: ``` static void A<T>::type() [with T = int&&] static void A<T>::type() [with T = float&] ```

Original source

Related problems