对C++ templates类模板的几点补充(Traits类模板特化)
前一篇文章《浅谈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);
}
对C++ templates类模板的几点补充(Traits类模板特化)的更多相关文章
- c++11-17 模板核心知识(二)—— 类模板
类模板声明.实现与使用 Class Instantiation 使用类模板的部分成员函数 Concept 友元 方式一 方式二 类模板的全特化 类模板的偏特化 多模板参数的偏特化 默认模板参数 Typ ...
- 音乐类产品——“网易云音乐”app交互原型模板(免费使用)
网易云音乐虽是一款音乐app,但有人说它也是社交界的一股清流以及一匹黑马.音乐带给人的感染,激发着很多人在这里表达着他们的情绪和心声.网易云音乐上的真实用户点评,不仅被印在地铁的广告牌上,还在朋友圈频 ...
- c/c++ 模板与STL小例子系列<二> 模板类与友元函数
c/c++ 模板与STL小例子系列 模板类与友元函数 比如某个类是个模板类D,有个需求是需要重载D的operator<<函数,这时就需要用到友元. 实现这样的友元需要3个必要步骤 1,在模 ...
- flask模板的基本用法(定界符、模板语法、渲染模板),模板辅助工具(上下文、全局对象、过滤器、测试器、模板环境对象)
flask模板 在动态web程序中,视图函数返回的HTML数据往往需要根据相应的变量(比如查询参数)动态生成. 当HTML代码保存到单独的文件中时,我们没法再使用字符串格式化或拼接字符串的当时在HTM ...
- C++反射机制:可变参数模板实现C++反射(使用C++11的新特性--可变模版参数,只根据类的名字(字符串)创建类的实例。在Nebula高性能网络框架中大量应用)
1. 概要 本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在码云的仓库地 ...
- Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...
- eclipse 中 Servlet 模板代码(其实是代码提示模板)
说的是模板代码,应该说的是提示的模板代码,并不是一新建就会出现模板. 第一步:先建一个Servlet文件,写好自己想要的模板 我的模板如下: 全选并复制,等会要粘贴到Servlet的提示模板中. pa ...
- c++中模板是什么?为什么要定义模板?
一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...
- 【转载】ASP.NET工具类:文件夹目录Directory操作工具类
在ASP.NET开发网站的过程中,有时候会涉及到文件夹相关操作,如判断文件夹目录是否存在.删除文件夹目录.创建文件.删除文件.复制文件夹等等.这一批有关文件目录的操作可以通过Directory类.Fi ...
随机推荐
- python计算MD5
python有自带的MD5模块hashlib,用起来简单很多.Python Hashlib模块的使用说明 http://docs.python.org/2/library/hashlib.htmlfd ...
- 仿制用友U8界面
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- uva 508 - Morse Mismatches(摩斯码)
来自https://blog.csdn.net/su_cicada/article/details/80084529 习题4-6 莫尔斯电码(Morse Mismatches, ACM/ICPC Wo ...
- JS正则表达式笔记
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个条件的子串等. 正则 描述 ...
- easyui combox 随便不存在的值,清空
onHidePanel: function () { var valueField = $(this).combobox("options").valueField; var va ...
- 删除txt文件内容
删除txt文件里的 聊天记录的时间那一行 f = open("d:\\面试.txt", "r") g = open("d:\\英雄联盟ADC技巧.tx ...
- 在Linux中安装和配置OpenVPN Server的最简便方法!
本文介绍了如何在基于RPM和DEB的系统中安装和配置OpenVPN服务器.我们在本文中将使用一个名为openvpn-install的脚本,它使整个OpenVPN服务器的安装和配置过程实现了自动化.该脚 ...
- 【jQuery】 常用函数
[jQuery] 常用函数 html() : 获取设置元素内的 html,包含标签 text() : 获取设置元素内的文本, 不包含标签 val() : 获取设置 value 值 attr() : 获 ...
- 「个人训练」Can you solve this equation?(HDU-2199)
题意与分析 纯粹水题.本来想做下放松心情的,结果还是被坑了qaq 重点就是在浮点误差.比较左右的下次就直接上1e-10,别看着题目说1e-4然后给个-5,结果暴wa.气傻了..... 代码 #incl ...
- 适用于Linux的windows子系统
Windows基于图形界面的易用性是有目共睹的,这也是很多普通用户往往难以舍弃的原因.但是Linux系统更强大的网络应用开发能力,却又是Windows系统所无法比拟的.一直以来,很多人都在试图采用各种 ...