Consider the following program:
int add(int x, int y)
{
return x + y;
}
When this function is compiled, the compiler will determine that x + yevaluates to an int, then ensure that type of the return value matches the declared return type of the function (or that the return value type can be converted to the declared return type).
Return type deduction with auto
Since the compiler already has to deduce the return type from the return statement (to ensure that the value can be converted to the function’s declared return type), in C++14, the auto keyword was extended to do function return type deduction. This works by using the auto keyword in place of the function’s return type.
For example:
auto add(int x, int y)
{
return x + y;
}
Because the return statement is returning an int value, the compiler will deduce that the return type of this function is int.
When using an auto return type, all return statements within the function must return values of the same type, otherwise an error will result. For example:
auto someFcn(bool b)
{
if (b)
return 5; // return type int
else
return 6.7; // return type double
}
In the above function, the two return statements return values of different types, so the compiler will give an error.
If such a case is desired for some reason, you can either explicitly specify a return type for your function (in which case the compiler will try to implicitly convert any non-matching return expressions to the explicit return type), or you can explicitly convert all of your return statements to the same type. In the example above, the latter could be done by changing 5 to 5.0, but static_cast can also be used for non-literal types.
Benefits of return type deduction
The biggest advantage of return type deduction is that having the compiler deduce the function’s return type negates the risk of a mismatched return type (preventing unexpected conversions).
This can be particularly useful when a function’s return type is fragile (cases where return type is likely to change if the implementation changes). In such cases, being explicit about the return type means having to update all relevant return types when an impacting change is made to the implementation. If we’re lucky, the compiler will error until we update the relevant return types. If we’re not lucky, we’ll get implicit conversions where we don’t desire them.
In other cases, the return type of a function may either be long and complex, or not be that obvious. In such cases, auto can be used to simplify:
// let compiler determine the return type of unsigned short + char
auto add(unsigned short x, char y)
{
return x + y;
}