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