In c++03, the return type of a function template cannot is generalized if the return type relies on those of the template Arguments. Here's an example, Mul (t A, T B) is a function template, which calculates the product of A and B. Arguments A and B are of An arbitrary type T, which was not decided until the template instantiation. Thus, we cannot declare a return type for mul to generalize all the cases for a*b. If We must define such a function template, we have to introduce another template parameter as follows:
template<class T,class u>
U Mul (t A, T b) {
return a*b;
}
We have some trouble to instantiate this function template because we had to explicitly provide type U in the template in Stantiation. Can we use feature decltype to let the compiler deduce the result type automatically? See the following example:
Template<class t>
Decltype (a*b) mul (t A, T b) {
return a*b;
}
This program lets the compiler deduce the return type of function template Mul. Unfortunately, it doesn ' t work. The compiler is parsing codes from left to right, so it would issue an error message to indicate that variables A and B are Used before their declarations.
To solve this problem, C++11 introduced a feature called trailing return types. Using This feature, the previous program can be rewritten as follows:
Template<class t>
Auto Mul (t A, T B), Decltype (a*b) {
return a*b;
}
We Specify the function return type after the declaration of parameter declarations. Composite symbol->decltype (T1+T2) is called a trailing return type. The Auto keyword is placed before the function identifier, and which is the placeholder of the return type specifier. When a trailing return type was used, the placeholder return type must be auto. Meanwhile, the auto type specifier cannot is used in a function declaration without a trailing return type.
The biggest difference between ordinary functions and functions using trailing return types is whether to postpose the RET Urn types. See the following example:
Auto Max (int a, int b), int{}
Function Max is using a trailing return type, which are equal to int max (int a, int b). This example shows a valid scenario of trailing return types, but it doesn ' t reflect the benefits of this feature. We can fully enjoy the convenience of generic programming by using trailing return types. See the following example:
#include <iostream>
using namespace Std;
Template<typename T1, TypeName t2>
Auto Sum (T1 & T1, T2 & T2), decltype (t1 + T2) {
return t1 + T2;
}
int main () {
Auto i = 1;
Auto J = 1.3;
Auto k = SUM (a, b);
cout << c << Endl;
}
This program doesn ' t contain any explicitly specified types. All the types is deduced by the compiler using auto type deductions and trailing return types, which saves a lot of progr Amming efforts.
Another benefit of using trailing return types is the improvement of readability and maintainability of programs. See the following example:
Template <class t> class tmp{
Public
int i;
};
Tmp<int> (* (*foo ()) ()) () {
return 0;
}
Does feel terrible after reading? Actually, Foo is a function whose return type is a function pointer. The function pointer points to a function, that returns a function pointer. Using trailing return types, the previous program can be rewritten as follows:
Template <class t> class tmp{
Public
int i;
};
Auto Foo ()->auto (*) ()->tmp<int> (*) () {
return 0;
}
Do you see the magic of trailing return types in this example?
Besides the scenarios described above, trailing return types can also be used in function pointers, function references, M Ember functions in Classes/structures/class templates.
c++11:trailing return type in functions (back of function return types)