1.编译器断言

技巧大致跟后面的一样,都是利用偏特化,但是在C++ 0X里面已经有static_assert,所以感觉这东西也没什么用处了,更多的只是开阔眼界
2.偏特化
就是专门对一个类型去进行特殊的处理,毕竟template会给生成所有的类型相同的操作,但是有时候我们需要对特定的几个类型去处理,于是就有了特化和偏特化
3.局部类
一直被忽略的C++的语法,可以直接在类或者函数里面定义类,不过一直被忽视就对了,感觉这个还是挺有意思的
4.常数映射为型别:
template <int v>
struct Int2Type
{
     enum
     {
          value = v;
     }
}
这样的话,每次用不同的数字去实例化Int2Type,都是不同的类型
书中举了个反例
 <class T,bool flag>
class myclass
{
void DoSomething ()
{
if(flag )
{
T *new_obj = p_old_obj-> clone();
}
else
{
T *new_obj = new T(p_olb_obj );
}
}
};
 
 
上面的程序有两个问题
1.如果T的类型把复制构造函数声明为private或者protect,则编译错误
2.如果p_old_obj没事实现clone,则编译错误
 
我们可以这样改造下面的程序:
template <class T, bool isPolymorphic >
class NiftyContainer
{
private:
void DoSomething (T * pobj,int2type <true>)
{
T *pNewObj = pobj-> clone();
} void DoSomething (T * pobj,int2type <false>)
{
T *pNewObj = new T(pobj );
} public:
void DoSomething (T * pobj)
{
DoSomething(pobj ,int2type< isPolymorhpic>());
}
};
  
这样,只要你的程序有实现clone或者将复制构造函数设置为public,只要符合其中一个条件,就可以编译通过,而且选择什么动作是编译的时候就决定的
之所以只要实现clone或者public了复制构造函数就可以通过,是因为编译器不会去编译一个未用到的类成员函数
5.型别对型别的映射
在我们编程的时候,我们经常需要创建一个函数,用以产生一个新对象
template <class T, class U >
T *create (const U &arg )
{
return new T( arg);
}
  
那如果现在需要构造一个widget对象,但是这个对象需要-1作为构造参数,怎么办??
我们可以利用type2type来让编译器去选择我们要使用哪个模板函数
template <class T, class U >
T *create (const U &arg ,type2type< T>)
{
return new T( arg);
} template <class U>
widgets *create (const & arg,type2type <widgets>)
{
return new widgets( arg,-);
}
  
6,型别选择
有了前面的基础,看到后面的几个也就轻松,原理跟3(型别映射型别差不多)
其实就是利用函数的偏特化机制
template <bool flag, class T ,class U>
struct select
{
typedef T result;
}; template <class T, class U >
struct select <false, T,U >
{
typedef U result;
};
我们可以根据flag来在编译的时候就决定是要使用T还是使用U类型,不过这本书中的例子是用来选择是使用指针还是使用普通的类型,感觉这个例子没有traits好用
 
7.在编译期的时候确定一个类型是否可以转换成为另外一个类型(这样说感觉不怎么准确,更准确地说类型是否会隐式转换为另外一个类型)

template <class T, class U >
class conver
{
typedef char small; class big
{
char dummy [];
}; static small test( U); static big test(...); static T makeT();
public:
enum
{
exists = sizeof ( test( makeT() ) ) == sizeof(small )
};
};
 
这样,我们在写程序的时候,可以直接这样来判断一个类是否可以转换成另外一个类
算起来这个算是我觉得比较有趣的模板技巧了
 
1.实际上smalltest和bigtest还有makeT都没有实例化出来,因为sizeof并不会有实例化操作,所以即使没有定义函数,依然通过编译
 
2.多声明了一个makeT函数是因为一些类会把构造函数声明为私有的,如果不使用makeT,那么将无法调用T()
 
3.模板会寻找最佳匹配条件,也就是说,如果我们再多声明一个类型Z,把static big test(...)改成static big test(Z),那么在我们程序编译的时候,即使两个类型能够互相转换,比如int和size_t,那么编译器将会去调用test(Z),这样将无法看出两个类是否可以互相转换,反之,如果test是(...)这样声明的,那么编译器会认为test(U)比test(...)匹配,于是就去使用test(U)函数
 
8.type_info的外覆类
这个倒没什么,无非就是type_info无法复制,所以重新写了一个类包装下
 
9.定义Nulltype和emptyType复制类
也没什么好说的
 
10.traits
在前面的文章已经说过了
总的来说,要理解这些技巧,需要理解几点:
1.模板的特化
2.编译器是通过寻找最合适的匹配选项来匹配选择实例化的类型
 

C++编程新思维中的技巧的更多相关文章

  1. PowerBuilder编程新思维5:包装(界面美化与WebUI+React)

    PowerBuilder编程新思维5:包装(界面美化与WebUI+React) 前一节,分析了三种界面美化方案,都是控件级的美化.今天再来分析一下窗口级的美化.上一次讲的DirectUI,大家反响一般 ...

  2. PowerBuilder编程新思维3:适配(三层架构与GraphQL)

    PowerBuilder编程新思维3:适配(三层架构与GraphQL) PB在富客户端时代,是一线开发工具.随着网络发展,主流架构演进到三层架构的时代,PB拿不出有力的三层架构,已经明显力不从心,市场 ...

  3. PowerBuilder编程新思维2:嵌入(Thread多线程)

    PowerBuilder编程新思维2:嵌入(Thread多线程) 在PB中使用多线程,在网上有大量的文章介绍.不过深入研究并试着给出更易用的模型的,目前还只有"路人甲cw"的一篇& ...

  4. PowerBuilder编程新思维1:扩展(Lua)

    前言 PowerBuilder作为开发工具退出一线行列已经很久了,在2019年来谈这样一款老旧的编程工具是否有意义?诚然,PB有着太多硬伤,但还是有它的用武之地的.而且今天讲的这个“新思维”大部分内容 ...

  5. PowerBuilder编程新思维4:钩挂(界面美化与DirectUI)

    <第二部分 Outside> PowerBuilder编程新思维4:钩挂(界面美化与DirectUI) PB的界面由于其封闭性,一直以来都是最大的弱项.自PB9.0开放了PBNI接口后,开 ...

  6. 【响应式编程的思维艺术】 (2)响应式Vs面向对象

    目录 一. 划重点 二. 面向对象编程实例 2.1 动画的基本编程范式 2.2 参考代码 2.3 小结 三. 响应式编程实现 四. 差异对比 4.1 编程理念差异 4.2 编程体验差异 4.3 数学思 ...

  7. 《C++设计新思维》Command设计模式读后感

    原文内容提领: 本书第5章标题为泛化仿函数,我认为本章真正讲述的内容可以总结出一句话! 如何利用C++老标准实现C++11新标准类似std::function提供的功能. std::function简 ...

  8. java编程思想-java中的并发(一)

    一.基本的线程机制 并发编程使我们可以将程序划分为多个分离的.独立运行的任务.通过使用多线程机制,这些独立任务中的每一个都将由执行线程来驱动. 线程模型为编程带来了便利,它简化了在单一程序中同时jia ...

  9. Cocos2d-x 3.0final手机游戏开发视频教程2014 - 自学编程 -(陆续更新中)

    内容: 非常多人问我:沈老师,要不要更新引擎版本号到3.0,更新这么快,以后会不会每一个月都有一次,好怕呀. 我说:无论你曾经是哪个版本号,3.0final是一个架构级别的升级,能够在新项目中果断升级 ...

随机推荐

  1. python 数据结构之双向链表的实现

    和单链表类似,只不过是增加了一个指向前面一个元素的指针而已. 示意图: python 实现代码: #!/usr/bin/python # -*- coding: utf-8 -*- class Nod ...

  2. [转]在Eclipse中Debug 为什么显示source not found

    在Eclipse中Debug 为什么显示source not found http://zhidao.baidu.com/link?url=-jna2HB_k2FW72GPbT--5Qg2AWi3Ip ...

  3. int除以int 得到double类型值

    double serviceability =(double)(count1+count2)/sum; 需要进行强转 除数 这样得到的值就是double类型了

  4. 238. Product of Array Except Self

    Given an array of n integers where n > 1, nums, return an array output such that output[i] is equ ...

  5. 解决LinearLayout中控件不能居右对齐

    转载自:http://lgb168.blog.163.com/blog/static/49674438201172492935235/ 2011-08-24 21:35:25|  分类: Androi ...

  6. 传统解析xml的方式

    1. 介绍 1)DOM(JAXP Crimson解析器)          DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允 ...

  7. vim编辑器的基本操作

    1.安装vim编辑器 最小化安装的linux是没有vim编辑器的,需要手动安装 # yum -y install vim-enhanced # vim +2 123 直接到123的第2行 2.vim的 ...

  8. 《Java程序设计》第3周学习总结

    学号20145220<Java程序设计>第3周学习总结 教材学习内容总结 使用jave撰写程序几乎都在使用对象(Object),要产生对象必须先定义类(Class),类是对象的设计图,对象 ...

  9. python 核心编程第5章(习题)

    1.标准类型运算符. 写一段脚本,输入一个测验成绩,根据下面的标准,输出他的评分成绩(A-F). #coding:utf8 a = raw_input() a = int(a) if (a > ...

  10. WebForm 中的页面重定向和传值(转自 MSDN)

    ——原文地址:https://msdn.microsoft.com/zh-cn/library/6c3yckfw(v=vs.100).aspx      在开发 ASP.NET 网站时,您经常需要从一 ...