博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对C++ templates类模板的几点补充(Traits类模板特化)
阅读量:5899 次
发布时间:2019-06-19

本文共 2684 字,大约阅读时间需要 8 分钟。

前一篇文章《浅谈C++ templates 函数模板、类模板以及非类型模板参数》简单的介绍了什么是函数模板(这个最简单),类模板以及非类型模板参数。本文对类模板再做几点补充。

文章目录

1. 缺省的模板实参
2. Traits编程技法——以STL迭代器为例
1. 缺省的模板实参
这里依旧使用上一篇文章中的array类作为例子,其中有一处改变了——就是将unsigned int N = 10后面添加了一个默认的参数10:

template<typename T, unsigned int N = 10>

class array {
public:
array();
T& operator[] (unsigned int index);
constexpr unsigned int size() noexcept;
private:
T elems[N];
int length;
正是由于有默认的参数,所以如果没有指定array的大小的话,就会默认为10。

og::array<int> ai;

ai[0] = 4;
ai[2] = 123;
//ai[11] = 666; //exception
以上,并没有指定array大小为默认值10,所以ai[11]就出错了。

2. Traits编程技法——以STL迭代器为例

Traits技法主要是利用了“内嵌类型”的技巧,加上一部分编译器template参数推导的功能。能力十分强劲。咯,这里给出了一个迭代器的基类,让我们看一下STL是如何施展Traits技法的。

template <typename Category,

typename T,
typename Distance = ptrdiff_t,
typename Pointer = T*,
typename Reference = T&>
class iterator {//iterator base
public:
typedef Category iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
下面开始使用class template“萃取”迭代器的特性,直接祭出3个萃取器,我将它们命名为:main trait、pointer trait和pointer-to-const trait。

template <typename I>

class iterator_traits {//main trait
typedef typename I::iterator_category iterator_category;
typedef typename I::value_type value_type;
typedef typename I::difference_www.xgll521.com type difference_type;
typedef typename I::pointer pointer;
typedef typename I::reference reference;
};

template <typename I>

class iterator_traits<I*> {//pointer trait
typedef typename I::iterator_category iterator_category;
typedef typename I::value_type value_type;
typedef typename ptrdiff_www.thd178.com t difference_type;
typedef typename I* pointer;
typedef typename I& reference;
};

template <typename I>

class iterator_traits<const I*> {//pointer-to-const trait
typedef typename I::iterator_category iterator_category;
typedef typename I::value_type value_type;
typedef typename ptrdiff_t difference_type;
typedef typename I* pointer;
typedef typename I& www.gcyl152.com reference;
以上,你可能有两点疑惑。

其一,class iterator_traits<I*>这样的写法?这种其实叫做类模板的特化,第一个main trait被称为基本模板,后面的两个则为局部特化模板。我试了,必须要有基本模板,才能有局部特化模板,否则语法报错。

其二,类似于typedef typename I::pointer pointer;这样的写法?这里有两小点需要解释:

No.1 I::pointer 这里其实要求typename I传进来的必须是iterator base类,这样才能直接取类中的public成员变量。

No.2 我们常见的为typedef unsigned int size_t这样的写法?对typename balabala…的很不熟悉,这里举个例子你就熟悉了:

typedef struct node{

int data;
struct node* next;
}node_t;

node_t n1;

是不是有异曲同工之妙?

好了,开始另外一个话题—— 如何利用迭代器在编译时推断出类型?

直接看例子吧!这个函数可以很方便地决定某个迭代器的value_type。

template <typename Iterator>

inline typename iterator_traits<www.ysyl157.com Iterator>yongshiyule178.com::value_type* //返回值类型
value_type(const Iterator&) {
return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}

转载地址:http://kmhsx.baihongyu.com/

你可能感兴趣的文章
Unity Svn(转)
查看>>
设计模式(二)装饰器模式
查看>>
对图像进行压缩再进行圆形处理
查看>>
复制表结构和数据SQL语句
查看>>
Idea中使用Maven编码打包时中文乱码的解决办法
查看>>
图片margin:0 auto;为何不居中
查看>>
python基础===* 解包,格式化输出和print的一点知识
查看>>
使用User-Agent作为登录验证的一部分出现的问题
查看>>
《Python项目开发实战》--熟悉Python基础后我能做什么?
查看>>
mac安装memcache
查看>>
bzoj3143
查看>>
个人作业-Alpha项目测试
查看>>
分词之最短编辑距离算法实现(包括中文)
查看>>
从哪跌倒从哪爬起,千里之行始于足下
查看>>
四维偏序
查看>>
深入理解Java虚拟机
查看>>
oracle12c 可视化安装(桌面类)
查看>>
《黄昏清兵卫》中学到的工作态度
查看>>
构建之法阅读笔记04
查看>>
poj1580
查看>>