前一篇文章《浅谈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类模板特化)的更多相关文章

  1. c++11-17 模板核心知识(二)—— 类模板

    类模板声明.实现与使用 Class Instantiation 使用类模板的部分成员函数 Concept 友元 方式一 方式二 类模板的全特化 类模板的偏特化 多模板参数的偏特化 默认模板参数 Typ ...

  2. 音乐类产品——“网易云音乐”app交互原型模板(免费使用)

    网易云音乐虽是一款音乐app,但有人说它也是社交界的一股清流以及一匹黑马.音乐带给人的感染,激发着很多人在这里表达着他们的情绪和心声.网易云音乐上的真实用户点评,不仅被印在地铁的广告牌上,还在朋友圈频 ...

  3. c/c++ 模板与STL小例子系列<二> 模板类与友元函数

    c/c++ 模板与STL小例子系列 模板类与友元函数 比如某个类是个模板类D,有个需求是需要重载D的operator<<函数,这时就需要用到友元. 实现这样的友元需要3个必要步骤 1,在模 ...

  4. flask模板的基本用法(定界符、模板语法、渲染模板),模板辅助工具(上下文、全局对象、过滤器、测试器、模板环境对象)

    flask模板 在动态web程序中,视图函数返回的HTML数据往往需要根据相应的变量(比如查询参数)动态生成. 当HTML代码保存到单独的文件中时,我们没法再使用字符串格式化或拼接字符串的当时在HTM ...

  5. C++反射机制:可变参数模板实现C++反射(使用C++11的新特性--可变模版参数,只根据类的名字(字符串)创建类的实例。在Nebula高性能网络框架中大量应用)

    1. 概要   本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在码云的仓库地 ...

  6. Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

    上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...

  7. eclipse 中 Servlet 模板代码(其实是代码提示模板)

    说的是模板代码,应该说的是提示的模板代码,并不是一新建就会出现模板. 第一步:先建一个Servlet文件,写好自己想要的模板 我的模板如下: 全选并复制,等会要粘贴到Servlet的提示模板中. pa ...

  8. c++中模板是什么?为什么要定义模板?

    一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...

  9. 【转载】ASP.NET工具类:文件夹目录Directory操作工具类

    在ASP.NET开发网站的过程中,有时候会涉及到文件夹相关操作,如判断文件夹目录是否存在.删除文件夹目录.创建文件.删除文件.复制文件夹等等.这一批有关文件目录的操作可以通过Directory类.Fi ...

随机推荐

  1. C# WebClient类上传和下载文件

    这篇文章主要介绍了C# WebClient类用法实例,本文讲解使用WebClient下载文件.OpenWriter打开一个流使用指定的方法将数据写入到uri以及上传文件示例,需要的朋友可以参考下   ...

  2. python练习笔记

    python练习笔记,装饰器.定制方法生成特定的类 # -*- coding: utf-8 -*- def catch_exception(func): def wrap(self, *args, * ...

  3. Django之模型---ORM简介

    ORM ORM,是“对象-关系-映射”的简称,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因 ...

  4. 【Markdown】Markdown的使用(自用)

    # 欢迎使用 Cmd Markdown 编辑阅读器 我们理解您需要更便捷更高效的工具记录思想,整理笔记.知识,并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 -- 我们为记录 ...

  5. node获取URL数据

    req.method  -->GET req.hostname  -->127.0.0.1 req.originalUrl  -->/test/test/test?name=wang ...

  6. 对C语言连等式的学习

    例子如下 [pgsql@localhost soft]$ cat test1.c #include <stdlib.h> #include <stdio.h> int main ...

  7. 从C到C++ (3)

    从C到C++ (3) 一.    C++中增加了引用 1.引用是给某一个变量起别名.引用的一般格式: 类型 &引用名 = 变量名 定义引用时一定要初始化.在实际应用中,引用一般用作参数传递与返 ...

  8. centos7下安装oracle11gR2的详细步骤

    环境准备 安装包: CentOS-7-x86_64-DVD linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip 本教 ...

  9. 形象的理解Strong和Weak

    Strong Weak

  10. 【廖雪峰老师python教程】——模块

    使用模块 任何模块代码的第一个字符串都被视为模块的文档注释: 使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名: 当我们在命令行运行模块文件时,Python解释器把 ...