C++必知必会(5)

条款47模板局部特化

不能对函数模板进行局部特化,所能做的即使重载它们。

但可以对类模板进行局部特化。

template<typename T> class Heap;      //主模板

template<typename T> classHeap<T*>{…}; //局部特化

局部特化的语法类似完全特化,但是他的模板参数列表是非空的。当使用任何(未经修饰的)指针类型来实例化一个Heap时,这个局部特化版将优先于主模板而被采用。进一步而言,当模板实参类型为const char*或char*时,针对const char*和char*的完全特化版本的Heap又将优先于这个局部特化而被采用。

主模板的完全特化或局部特化必须采用与主模板相同数量和类型的实参进行实例化,但它的模板参数列表并不需要具有和主模板相同的形式。对于Heap来说,主模板带有单个类型名字参数,因此Heap的任何完全特化或局部特化都必须通过采用单个类型名字实参来实例化。

template<>class Heap<const char*>{…};    //完全特化,带有单个类型名字模板

//实参,但模板参数列表不同于主模板参数列表,完全特化的模板参数是空的

template<typenameT> classHeap<T*>{…}; //局部特化,带有单个类型实参,模板参//数列表也可以带有单个类型名字参数,但不是必须的,如下

template<typenameT,int n> classHeap<T[n]>{…};    //局部特化,带有单个类型实参,    但该参数必须是一个具有n个类型为T的元素的数组

条款48类模板成员特化

对主模板而言,类模板的完全特化和局部特化全然是单独的实体,他们不从主模板“继承”任何接口或实现。但通常期望能有和主模板一套相同的接口。

template<typenameT>

class Heap

{

public:

void push(const T& val);

};

可以不针对模板进行特化,只针对模板成员函数特化。

template<>

void Heap<const char*>::push(constchar* const &pval){…}

注意,这些函数的接口必须和进行成员特化的模板对的相应接口精确匹配。例如,主模板将push声明为带有一个类型为const T &的参数,因此针对const char*的push显式特化的实参必须为const char* const &。

如果已存在针对一般指针的Heap局部特化,

template<typenameT>

class Heap<T*>

{

void push(T*pval);

};

如果这个局部特化已经存在,那么对push的显式特化就必须符合该局部特化中push成员接口,因为该函数相当于针对Heap<const char*>进行实例化所得的结果。所以,显式特化现在必须声明为:

template<>

void Heap<constchar*>::push(const char* pval){…}

条款49利用typename消除歧义

使用tepename关键字可以明确地告诉编译器,接下来的限定名字是一个类型名字,从而允许编译器去正确的解析模板。这个关键字经常被用在说明嵌套类型中。

模板50成员模板

一个成员模板就是一个自身是模板的成员。

template <typename T>

class Slist{

public:

//…

template<typenameIn> Slist(In begin, In end);

};

template<typename T>

template<typename In>

SList<T>::SList(In begin, In end) :head_(0){

while(begin!= end)

push_front(*begin++);

reverse();

}

条款51 采用template消除歧义

std配置器中的rebind是一个模板,当如下定义式将会出错:

template<typename T, class A =std::allocator<T>>

class SList{

//…

structNode{

//…

};

typedefA::rebind<Node>::other NodeAlloc;       //语法错误!

//…

};

解决办法:

typedef typename A::template rebind<Node>::otherNodeAlloc;

使用关键字template,即等于告诉编译器,rebind是一个模板,而使用typename则等于告诉编译器,整个这一堆东西表示的是一个类型名字。

条款52针对类型信息的特化

可以从一个特化版本中推导出类型的属性。让我们看一个简单的例子:

template <typename T>

struct IsInt    //T表示一个int

{

enum{result = false};

};

template<>

struct IsInt<int>   //除非是一个int

{

enum{result= true};

};

有了这个主模板和完全特化版本,就可以在编译器询问一个未知的类型是否确实为int:如下

template<typenameX>

void aFunc(X&arg){

//…

…IsInt<X>::result…

//…

}

条款53 嵌入的类型信息

template<class T>

class Seq{

public:

typenameT Elem;             //元素类型

typenameT Temp;            //临时对象的类型

size_tsize()  const;

//…

};

在编译期可以查询到这种嵌入的信息:

typedef Seq<std::string> Strings;

//…

Strings::Elem aString;

条款54traits

http://blog.csdn.net/walkerkalr/article/details/17287939条款47:请使用traitsclasses表现类型信息

C++必知必会(5)

时间: 2024-10-22 02:56:13

C++必知必会(5)的相关文章

MySQL必知必会 学习笔记(一)

第一章  了解SQL 模式:   关于数据库和表的布局以及特性的信息.[描述表可以存储什么样的数据,数据如何分解,各部分信息如何命名等等,可以用来描述数据库中特定的表以及整个数据库(和其中表的关系)]. 第二章 MySQL简介 MySQL是一种DBMS,即它是一种数据库软件.基于客户机----服务器的数据库. MySQL工具: 1.mysql 命令行实用程序 2.MySQL Administrator 3.MySQL query Browser 第四章 检索数据 LIMIT 5 表示MySQL返

mysql 必知必会总结

以前 mysql 用的不是很多, 2 天看了一遍 mysql 必知必会又复习了一下基础.  200 页的书,很快就能看完, 大部分知识比较基础, 但还是了解了一些以前不知道的知识点.自己做一个备份,随时查看. 命令:sql 不区分大小写,语句大写,列.表名小写是一种习惯连接命令:mysql -u user_name –h example.mysql.alibabalabs.com –P3306 –pxxxxquithelp show; // 查看所有 show 命令show databases;

JSON必知必会学习总结(一)

七月第一周,从学校毕业回来上班的第一周.离开一段时候后,再次回来重新工作,有了很多新的认识,不再是实习时那么混混沌沌了.每天我自己该做什么,怎么做,做到什么程度更清晰了.除了要去完成我负责的工作,我开始去想除了完成工作我要从中获得什么. 今天早晨走的时候,随手塞包里一本薄薄的书--<JSON必知必会>,白天间隙的时候看了前两章,这两章设计的内容平时基本接触过,但是没有系统的总结过,看完之后清晰了很多. 首先,JSON是什么,这本书是说JSON是一种数据交换格式,被许多系统用于数据交换. 数据交

SQLServer:《SQL必知必会》一书的读书笔记(五)

第5课 高级数据过滤 5.1 组合 WHERE 子句 第4课介绍的 WHERE 子句在过滤数据时都是用单一的条件. 5.1.1 AND 操作符 检索由供应商 DLL01 制造且价格小于等于 4 美元的所有产品的名称和价格: SELECT prod_id, prod_price, prod_name FROM Products WHERE vend_id = 'DLL01' AND prod_price <= 4; 5.1.2 OR 操作符 检索任一个指定供应商制造的所有产品的名称和价格: SEL

.NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)

Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一些列是使用.NET/C#来展现,但是同样适用于其他类似的OO技术平台,这些技术点可能称不上完整的技术,但是它是经验的总结,是掉过多少坑之后的觉醒,所以有必要花几分钟时间记住它,在真实的项目开发中你就知道是多么的有帮助.好了,废话不说了,进入主题. 我们在开发服务时为了调试方便会在本地进行一个基本的模块测试,你也可以认为是集

《MySQL必知必会》读书笔记_4

PS:一个实际的存储过程案例 CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_delete_article_by_id`(IN `id` int) BEGIN #Routine body goes here... DECLARE temp INT; SET @aid = id; SELECT COUNT(*) FROM gk_reply_article WHERE a_id = @aid INTO temp; IF(temp <> 0) THEN

移动前端开发人员必知必会:移动设备概述

因为工作岗位的变换带来工作内容的变动,对于移动网站的前端开发已经疏远了好几个月,在这好几个月中有很多新的东西出现,自己所掌握的一些东西也已经陈旧,所以选择了这本书<HTML5触摸界面设计与开发>来系统地学习和整理一下关于移动网站前端开发的知识体系. 之所以选择这本书,一是因为这本书比较新,2014年04月发的第一版.其二是因为作者Stephen Woods,这是Flickr团队的资深前端,Yahoo主页的Javascript技术平台正是出自此人之手. 接下来的时间里会陆续上传关于这本书学习的一

mysql学习--mysql必知必会1

?? 例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式处理. (.)是正則表達式的一个符号,表示匹配随意一个字符: mysql> select prod_name -> from products -> where prod_name regexp '.000' -> order by prod_name; +--------------

《MySQL 必知必会》读书总结

这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. ? ? 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter password:****** 显示数据库 mysql>SHOW DATABASES; 选择数据库 mysql>USE mytest; 显示数据库中的表 mysql>SHOW TABLES; 显示表列 mysql>SHOW COLUMNS FROM tmall_user; mysql

rime 必知必會

https://github.com/rime/home/wiki/CustomizationGuide Rime 定製指南 必知必會 建議您在定製 Rime 輸入法之前瞭解 Rime 輸入方案的概念.Rime 中的數據文件分佈及作用等基礎知識. 必知必會 重新佈署的操作方法 [中州韻]點擊輸入法狀態欄上的 ? (Deploy) 按鈕 或:如果找不到狀態欄,在終端輸入以下命令,可觸發自動部署: rm ~/.config/ibus/rime/default.yaml; ibus-daemon -d