Using auto as a return type is another feature which is new in C++11. The feature has a bit unusual syntax at first sight.

If there is a function with return type T

T function();

it is equivalent to write

auto function() -> T;

This is just another way of saying that the return type of function is T.

But why should we use this notation? It looks more complicated and we need to type more. Well, there is a reason. But before I tell you the reason, we should look at another C++11 feature: decltype.

Decltype

Rule of thumb is that decltype(argument) tells you the type of argument. For example, the program

int main()
{
    int i = 1;
    double d = 1.0;

    std::cout << std::is_same<int, decltype(i + i)>::value << "\n"
              << std::is_same<double, decltype(d + i)>::value << "\n"
              << std::is_same<int, decltype(d + i)>::value << "\n"
              << std::endl;
    return 0;
}

outputs

1
1
0

The result of expression i + i is int, thus std::is_same<int, decltype(i + i)>::value is true. A similar argument tells us the types of other expressions.

Usually decltype tells us what we want, but there are some corner cases which give us a result we might not expect. For example, running this program

int main()
{
    int i = 1;
    std::cout << std::is_same<int, decltype(i)>::value << "\n"
              << std::is_same<int, decltype((i))>::value << "\n"
              << std::is_same<int&, decltype((i))>::value << "\n"
              << std::endl;
    return 0;
}

produces the following output

1
0
1

We notice that decltype(i) deduces to int and decltype((i)) deduces to int&.

Therefore, when you use decltype, you should check its rules for deducing types.

Using decltype

Now, we are going back to the reason for

auto function() -> T

Using decltype, we can define the following function

auto fun(int i) -> decltype(i + i)
{
    return i + i;
}

The return type of fun is int, because the type of the expression i + i is equal to int.

But in this case it is not possible to write something like

decltype(i + i) fun(int i)
{
    return i + i;
}

Because when compiler reaches decltype(i + i) it does not know what i is. Consequently, the compiler is not able to figure out the return type of fun. Therefore, we have to use the former version of the return type declaration.

C++14

We should note that for C++14 the following

auto fun(int i) -> decltype(i + i)
{
    return i + i;
}

is equivalent to

decltype(auto) fun(int i)
{
    return i + i;
}

In this case, decltype(auto) indicates that the return type of fun is equal to decltype of the return expression.

Summary

We learned a new feature: how to declare a return value of a function using auto keyword. We also looked at the decltype specifier.

Links: