Before C++14, when implementing a function template, programmers did not know the return type of their functions and had to do something like this:
template <typename A, typename B>
auto do_something(const A& a, const B& b) -> decltype(a.do_something(b))
{
return a.do_something(b);
}
Programmers had to use decltype to tell the compiler: “The return type of this method is the return type of the do_something method of object a.” The auto keyword was used to inform the compiler: “The return type of this function is declared at the end.”
Since C++14, coders can do something much simpler:
template <typename A, typename B>
auto do_something(const A& a, const B& b)
{
return a.do_something(b);
}
Starting with C++14, the compiler deduces the return type of functions that use auto as the return type.
Restrictions:
All returned values must be of the same type. The example below will not even compile because it can return either an int or a double:
auto f(int n)
{
if (n == 1)
{
return 1;
}
return 2.0;
}
For recursive functions, the first return value must allow the compiler to deduce the return type of the function, as in this example:
auto accumulator(int n)
{
if (n == 0)
{
return 0;
}
return n + accumulator(n - 1);
}
Starting with C++20, a function can be declared like this and it will work properly:
auto do_something(const auto& a, const auto& b)
{
return a.do_something(b);
}
When programmers define functions this way, if one or more function parameters are declared as auto, the entire function is treated as a template. So, while this new construction might seem to add more “functionality” to the auto keyword, it is really just a more convenient way of declaring function templates.
More posts about auto: