Trailing return type (C++11)
The trailing return type feature removes a C++ limitation where the return type of a function template cannot be generalized if the return type depends on the types of the function arguments. For example, a and b are arguments of a function template multiply(const A &a, const B &b), where a and b are of arbitrary types. Without the trailing return type feature, you cannot declare a return type for the multiply function template to generalize all the cases for a*b. With this feature, you can specify the return type after the function arguments. This resolves the scoping problem when the return type of a function template depends on the types of the function arguments.
Trailing return type syntax >>-function_identifier--(--+-----------------------+--)---------> '-parameter_declaration-' >--+------------------+--+-----------------------+--------------> '-cv_qualifier_seq-' '-exception_declaration-' >-- -> -return_type--------------------------------------------><
- This syntax is not the one for a function declaration or definition. The auto placeholder occurs in the syntax for declarations and definitions where they specify return_type_specifier.
- As with function declarators without a trailing return type, this syntax might be used to declare a pointer or reference to function.
- More complex types might be formed by using the syntax of direct_declarator in place of function_identifier. For the details of direct_declarator, see Overview of declarators.
To use the trailing return type feature, declare a generic return type with the auto keyword before the function identifier, and specify the exact return type after the function identifier. For example, use the decltype keyword to specify the exact return type.
// Trailing return type is used to represent
// a fully generic return type for a+b.
template <typename FirstType, typename SecondType>
auto add(FirstType a, SecondType b) -> decltype(a + b){
return a + b;
}
int main(){
// The first template argument is of the integer type, and
// the second template argument is of the character type.
add(1, 'A');
// Both the template arguments are of the integer type.
add(3, 5);
}
- When a trailing return type is used, the placeholder return type must be auto. For example, the statement auto *f()->char results in a compile-time error, because auto * is not allowed as the placeholder return type.
- The auto type specifier can be used with a function declarator with a trailing return type. Otherwise, the auto type specifier is used in accordance to the auto type deduction feature. For more information about auto type deduction, see The auto type specifier (C++11). Because a function declaration cannot have an initializer as required for auto type deduction, the auto type specifier cannot be used in a function declaration without a trailing return type. For declarations of pointers and references to functions, the auto type specifier can be used with either a corresponding trailing return type or an initializer. For details of pointers and references to functions, see Pointers to functions.
- The return type of a function cannot be any of the following types:
- Function
- Array
- Incomplete class
- The return type of a function cannot define any of the following
types:
- struct
- class
- union
- enum
template <class A, class B> class K{
public:
int i;
};
K<int, double> (*(*bar())())() {
return 0;
}
template <class A, class B> class K{
public:
int i;
};
auto bar()->auto(*)()->K<int, double>(*)(){
return 0;
}
struct A{
typedef int ret_type;
auto bar() -> ret_type;
};
// ret_type is not qualified
auto A::bar() -> ret_type{
return 0;
}
double number (int a){
return double(a);
}
int number(double b){
return int(b);
}
template <class A>
auto wrapper(A a) -> decltype(number(a)){
return number(a);
}
int main(){
// The return value is 1.000000.
wrapper(1);
// The return value is 1.
wrapper(1.5);
}
In this example, the wrapper function
and the number function have the same return type.