对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 ...
随机推荐
- 【rip-基础配置】
配置rip,默认rip id为 1:rip有version1和version2两个版本;宣告与rip直连的网段; 优化rip: [interface_name] rip poison-reverse ...
- python中字典的遍历
用ipython运行情况如下: #新建字典 In [1]: name_cards = {'name':'sunwukong','QQ':'123124','addr':'秦皇岛'} #生成key对象 ...
- 嵌入式框架Zorb Framework搭建三:列表的实现
我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...
- 数据库 MySQL part2
表记录的操作 增 1.插入一条记录 语法:insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......); ...
- mysql用命令创建用户创建数据库设置权限
1.create database bbs; //创建数据库 2.create user bbs IDENTIFIED by 'bbs'; //创建用户bbs和登录密码bbs 3.grant AL ...
- ip4addr_ntoa和不可重入函数
在网络中,有一个转换IP地址到ASIIC字符串的函数,该函数的返回值所指向的ASIIC字符串驻留在静态内存中,所以该函数不可重入. 通俗的讲,在多任务系统中,一个任务执行在调用运行这个函数的时候,其他 ...
- C#读写txt文件的两种方法介绍 v
C#读写txt文件的两种方法介绍 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出 ...
- 步骤:asp.net core中使用identifyserver4颁发令牌
使用IdentityServer4颁发令牌基本步骤如下: 在 Startup.Configure 方法调用 app.UseIdentityServer ,添加IdentityServer4到应用的 H ...
- Java日志(一):log4j与.properties配置文件
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录,在Apache网站jakarta.apache.org/log4j可以免费下载到Log4j ...
- 做模态弹框的时候,防止背景滚动方法 移动端 html5
$(window.document).bind("touchmove", function() { return false; });