C++ Traits的笔记

发布时间 2023-04-11 20:30:21作者: ecnu_lxz

traits意思为特性,特点
在C++中用于提取类型信息
#include<type_traits>
type_traits库中有std::is_same可以判断两个类型是否相同

先看一下使用模板提取类型信息,就是多做一层封装
在使用模板的过程中
假设函数中有必要声明一个变量,要和迭代器所指向的对象类型相同

template <class I, class T>
void func_impl(I iter, T t) {
        T tmp; // T就是得到的类型信息
}

template <class I>
inline void func(I iter) {
        func_impl(iter, *iter); // 传入iter和iter所指的值,class自动推导
}

int main() {
    int i;
    func(&i);
}

func_impl就得到了迭代器的类型T,因为func中降迭代器iter所指的值传给了func_impl
但这种方式无法推导函数的返回值类型,有时我们在写代码时,函数前面的返回类型要确定为某个类
对于返回值如何推导?看看模板偏特化的神通

一个解决方法是,在定义类时,内嵌类型声明

template <class T>
struct ABC{
    typedef T value_type; // 内嵌类型声明
    // ...
};

但原生指针不是类别,无法内嵌类型信息,所以要对原生指针类做一个模板特化

由模板的偏特化,不同类型匹配不同的模板实现
如下代码所示,指针类型的变量会匹配指针偏特化的模板
利用这一点,对关心的几种类型做偏特化,就可以将某个类型的对象匹配到对应的模板实现上
而类型信息在这种情况下就是已知的了

 //自定义的类内部需要内嵌value_type变量
 template <class T>
 struct iterator_traits {
     typedef typename T::value_type value_type;
 };
 
 //模板偏特化,指针类型
 template <class T>
 struct iterator_traits<T*> {
 //指针类型匹配在此,value_type就正确对应到指针的类型T了,而不是T*
     typedef T value_type;
 }; 

 template <class T>
 typename iterator_traits<T>::value_type func(T it) {
     return *it;
 }

func(T it)传入实参时,该函数的返回值是iterator_traits<T>::value_type
T为实际类型,会和模板类iterator_traits进行匹配(模板实例化,但没有创建iterator_traits结构体变量),value_type会获得正确的类型
从而返回值的类型也推导出来了
普通的类中需要定义好value_type,指针类别无需

参考了这篇文章,写得不戳 https://www.cnblogs.com/mangoyuan/p/6446046.html