1.介绍
返回类型后置(Trailing return type)是 C++11 引入的一种新的函数声明和定义语法,它允许将函数的返回类型放在函数参数列表之后,使用 ->
符号来指定。
为什么要引入返回类型后置?因为在泛型编程中,模版函数的返回值类型取决于模版参数,如果使用decltype来推导返回值类型写法过于复杂。因此引入返回类型后置来解决该问题。
引入之前推导:
template <typename T, typename U>
decltype((*(T*)0) + (*(U*)0)) add(T t, U u)
{
return t + u;
}
引入之后推导:
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u)
{
return t + u;
}
代码的复杂度和可读性都得到了优化。
2.用法
(1) auto add(int a, int b) -> int
这里auto是个占位符,它告诉编译器返回值类型由->后指定,这里->后是具体类型,直接指明返回值类型为int。
(2) auto add(T t, U u) -> decltype(t + u)
这里auto是个占位符,它告诉编译器返回类型由->后的decltype指定。decltype根据exp表达式推导出返回值类型。
不了解auto与decltype的读者可以参考一下——C++11新特性之auto-优快云博客和C++11新特性之decltype-优快云博客。
3.使用场景
(1)当函数的返回类型依赖于其参数的类型时,返回类型后置语法可以用 decltype
来推导返回类型。例如,在一个函数中根据传入的参数进行不同类型的计算,返回结果的类型取决于参数的类型:
template<typename T, typename U>
auto multiply(T a, U b) -> decltype(a * b) {
return a * b;
}
这里 decltype(a * b)
会根据a和b的实际类型推导出a*b 表达式的类型,作为函数的返回类型。
(2)对于一些复杂的返回类型,如嵌套的模板类型或需要通过类型特征(type traits)来推导的类型,返回类型后置可以使代码更易读。例如:
template<typename T>
auto createVector() -> typename std::vector<typename std::remove_reference<T>::type> {
return std::vector<typename std::remove_reference<T>::type>();
}
在这个例子中,返回类型是一个嵌套的模板类型,使用返回类型后置可以将复杂的类型推导部分放在函数参数列表之后,使函数声明的主体部分更清晰。
4.总结
优点:
(1)提高了代码的可读性。
(2)支持依赖参数的返回类型推导。
注意事项:
(1)auto在其中只是个占位符,不参与推导,真正的返回类型由->后的类型决定。
(2)在使用时确保表达式格式与逻辑正确,否者可能会导致编译错误。