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. 2015GitWebRTC编译实录7

    2015.07.20 libvoiceengine 编译通过去除了mock测试代码,mock是用来进行测试的,意义不大.另外会报一个常量错误,需要定义WEBRTC_MAC宏,只定义WEBRTC_IOS ...

  2. IOKit找不到问题定义

    Xcode511下Undefined symbols for architecture armv7s:  "_IOMasterPort", referenced from:     ...

  3. OnItemSelectedListener事件与二级联动

    一.界面 1.新建province.xml件. 在“res/values”位置新建province.xml文件. (1)province.xml文件位置如下图所示: (2)province.xml内容 ...

  4. JS的prototype的共享机制分析

    function Super(){ } Super.prototype.aaa=[1,2,3]; Super.prototype.bbb=1; function Sub(){ Super.call(t ...

  5. QT GUI @创建新的工程

    开发环境: Qt 4.5 Qt Creator 1.3.0 新工程创建步骤: 1. 单击运行Qt Creator,进入欢迎页面.选择"File" -> "New F ...

  6. CentOS怎样强制卸载PHP以及自定义安装PHP

    很无语,CentOS居然php版本才5.1.6,很多开源的CMS无法安装. 查看php版本命令: #php -v 这个命令是删除不干净的 #yum remove php 因为使用这个命令以后再用 #p ...

  7. c++特性:指向类成员的指针和非类型类模板参数和函数指针返回值 参数推导机制和关联型别

    一.c++允许定义指向类成员的指针,包括类函数成员指针和类数据成员指针 格式如下: class A { public: void func(){printf("This is a funct ...

  8. ToDictionary,ToLookup

    这个系列我们看看C#中有哪些我们知道,但是又不知道怎么用,又或者懒得去了解的东西,比如这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,其中ToAr ...

  9. HBase 建表新增数据记录

    login as: root root@192.168.12.23's password: ********* Last login: Wed Aug 20 00:41:17 2014 from 19 ...

  10. unity Dotween插件的简单介绍及示例代码

    unity里面做插值动画的插件有许多,比较常见的有itween.hotween.dotween.根据大家的反馈和实际体验来说,dotween插件在灵活性.稳定性.易用性上都十分突出.这里简单介绍下它的 ...