2019/06/19
5,570
今天在看 cpprestsdk 的源码的时候发现一个方法的定义是这样的:
template<typename _Ty>
__declspec(noinline) auto create_task(_Ty _Param, task_options _TaskOptions = task_options())
-> task<typename details::_TaskTypeFromParam<_Ty>::_Type>
{...}
语法为:
auto fun_name(argument-declarations...) -> return_type{}
我们知道 C++11 的 lambda 表达式可以使用 `->` 指定返回参数的类型, 没想到声明方法也可以这么用。这种写法和传统的方法有什么区别呢?
在泛型编程中,一个常见的例子如下:
template <typename T>
T add(T a, T b) {
return a + b;
}
如果 `a` 和 `b` 的类型不同,需要怎么写呢?
template<typename R, typename T1, typename T2>
R add(T1 a, T2 b) {
return a + b;
}
auto ret_val = add<float>(1.0, 2);
auto ret_val1 = add<decltype(1.0 + 2)>(1.0, 2);
我们在调用此方法时必须显示指定 `R` 的类型, 或者使用 `decltype` 运算符推导返回值类型。如果让调用的方式简单点呢?把返回值类型放到定义中去, 像这样:
template <typename T1, typename T2>
decltype(a + b) add(T1 a, T2 b) {
return a + b;
}
然而这么写是编译不过的。因为 `a`, `b` 在参数列表中,编译器解析返回值的时候,它们还没有定义。那么我们可以这样写:
template <typename T1, typename T2>
decltype((*(T1*)0) + (*(T2*)0)) add(T1 a, T2 b) {
return a + b;
}
不过这太晦涩了。
C++ 11 允许将返回值类型后置,前面使用 auto 占位: