【C++】模板 备忘

类型退化 std::decay

template<class T>
struct decay;
  • T类型U的数组 / 对类型U的数组的引用, 则退化后的类型为U*
  • T为一个函数类型F/对函数的引用, 则退化后的类型为std::add_pointer<F>::type
  • 否则, 对其余所有类型, 其退化后的类型为 std::remove_cv<std::remove_reference<T>::type>::type

因此粗略来讲, decay将数组/函数类型退化为指针, 将其余的类型去除引用和const&volatile修饰符.

辅助类 decay_t<T>, 用于取出退化后的类型

template <class T>
using decay_t = typename decay<T>::type; // cpp14 

可能的实现

  1. 先去除T的引用, 得到类型U
  2. 若U是数组类型, 则去掉数组的修饰后的得到 变量类型V, V*就是退化类型
  3. 若U是函数类型, 则用 add_pointer 转为指针类型.
  4. 否则, 用remove_cv去除其可能的const/volatile修饰符.

转为指针类型 add_pointer

辅助类 add_pointer_t<T>

template <class T>
using add_pointer_t  = typename add_pointer<T>::type ; 

若T是引用类型, 则结果为指向其引用类型的指针. int& ==> int*
若T是个对象类型 或 无引用/cv 修饰的函数类型 或 void类型, 则返回T*
若T是个CV修饰/引用修饰的函数类型, 则只返回T

返回数组类型中的元素类型 std::remove_extent

std::extent 在cpp中指代的是数组定义中维度的部分(即数组长度 [N] )
用法 : std::extent<数组类型, 第N维 = 0>::value

std::extent<int[3][4]>::value ⇒ 3
std::extent<int[3][4], 1>::value ⇒ 4

因此std::remove_extent 就是返回数组定义中关于元素类型的部分: int[3][4] ---> int

参数包 Parameter pack

一个模板parameter pack是一个能接收0或多个模板实参(非类型实参/类型实参/模板)的 模板形参
一个函数parameter-pack是一个能接收0或多个函数实参的 函数形参

一个含有至少一个parameter-pack的模板被称为可变参数模板

语法

模板parameter-pack
用于 模板别名, 类模板, 变量模板, 函数模板的参数列表中

typename... 参数包名
template<参数列表>  typename ...  参数包名  // C++17以后

函数parameter-pack
声明中: 用在变参函数模板的函数参数列表中:
Ts… some_args

parameter-pack的展开
适用于在某个可变模板的定义中.
扩展为由逗号分割的含0或多个pattern的列表

eg : &args …
非类型的模板parameter-pack
类型模板parameter-pack
一个模板类型的模板parameter-pack
一个函数parameter-pack

返回可变参数总数 sizeof...(模板参数包)

返回公共父类型 std::common_type<T1,T2, ... >

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值