跟踪返回类型 (C++11)
如果返回类型依赖于函数自变量的类型,那么尾部返回类型功能将除去 C++ 限制,其中无法对函数模板的返回类型进行泛化。 例如, a 和 b 是函数模板 multiply(const A &a, const B &b)的自变量,其中 a 和 b 是任意类型。 如果没有尾部返回类型功能,那么无法声明 multiply 函数模板的返回类型以泛化 a*b的所有观测值。 通过此功能,可以在函数自变量后指定返回类型。 当函数模板的返回类型取决于函数自变量的类型时,这将解决作用域限定问题。
备注信息:
- 此语法不是函数声明或定义的语法。 自动占位符在其指定 return_type_说明符的声明和定义的语法中出现。
- 与没有尾部返回类型的函数声明符一样,此语法可用于声明函数的指针或引用。
- 可以使用 direct_声明者 的语法代替 function_identifier来构成更复杂的类型。 有关 direct_声明者的详细信息,请参阅 声明者概述。
要使用尾部返回类型功能,请在函数标识之前使用 auto 关键字声明通用返回类型,并在函数标识之后指定准确的返回类型。 例如,使用 decltype 关键字来指定精确的返回类型。
在以下示例中,
auto 关键字放在函数标识 add之前。 add 的返回类型为 decltype(a + b),这取决于函数自变量 a 和 b的类型。// 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);
}备注信息:
- 使用尾部返回类型时,占位符返回类型必须为
auto。 例如,语句auto *f()->char会导致编译时错误,因为不允许使用auto *作为占位符返回类型。 auto类型说明符可以与具有尾部返回类型的函数声明符配合使用。 否则,将根据自动类型扣除功能使用auto类型说明符。 有关自动类型扣除的更多信息,请参阅 自动类型说明符 (C++11)。 因为函数声明不能具有自动类型扣除所需的初始化方法,所以不能在没有尾部返回类型的函数声明中使用auto类型说明符。 对于对函数的指针和引用的声明,可以将auto类型说明符与相应的尾部返回类型或初始化方法配合使用。 有关指向函数的指针和引用的详细信息,请参阅 指向函数的指针。- 函数的返回类型不能是以下任何类型:
- 函数
- 数组
- 不完整的类
- 函数的返回类型无法定义以下任何类型:
structclassunionenum
此外,在函数具有复杂返回类型的情况下,此功能使您的程序更加紧凑和优雅。 如果没有此功能,那么程序可能很复杂且容易出错。 请参阅以下示例:
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;
}此功能还可用于类的成员函数。 在以下示例中,程序是简明的,因为在使用尾部返回类型之后,不需要限定成员函数
bar 的返回类型: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);
}
在此示例中, wrapper 函数和 number 函数具有相同的返回类型。