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. WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8

    转载自:http://blog.ready4go.com/blog/2013/05/18/resolve-android-ndk-warning-app-platform-android-14-is- ...

  2. HighChartS cpu利用率动态图(Java版)

    来源:http://www.cnblogs.com/haifg/p/3217699.html   最近项目需要监控服务器cpu的利用率,并做成动态图.在网上查找了一些资料,最终选择了HighChart ...

  3. 高逼格的画图:VIM原来可以这样玩

    在Linux上其实并不缺少画图软件(比如yEd等),那么为什么还需要用VIM来画图: 更轻,不需要安装太多东西 更小,就是一些文本,比图片什么的小多了,使用起来也更简单 更有逼格 那么我们该怎么做呢? ...

  4. 215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  5. c 函数及指针学习 9

    指针的高级应用 处理命令行参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>   int main(int ar ...

  6. c 函数及指针学习 6

    不完整声明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 /* 方法一   */ struct tag_a{ ...

  7. linux脚本编程技术---8

    一.什么是脚本 脚本是一个包含一系列命令序列的可执行(777)文本文件.当运行这个脚本文件时,文件中包含的命令序列将得到自动执行. 二.脚本编程 #!/bin/sh 首行固定格式 #!表明该脚本的的解 ...

  8. 4-3 yum命令

    1.常用yum命令 <1>查询 yum list #查询所有可用软件包列表(以 包名 - 版本 - yum源所在名称 格式显示) yum search 关键字 #搜索服务器上所有和关键字相 ...

  9. 记事本写JAVA程序

    编写程序源码: 1.新建记事本程序,修改文件名称为HelloWorld.java 打开编辑以下内容,保存. public class HelloWorld { public static void m ...

  10. 通过laravel理解IoC(控制反转)容器和DI(依赖注入)

    原文地址: http://www.insp.top/learn-laravel-container ,转载务必保留来源,谢谢了! 容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器 ...