C++编程新思维中的技巧

1.编译器断言

技巧大致跟后面的一样,都是利用偏特化,但是在C++ 0X里面已经有static_assert,所以感觉这东西也没什么用处了,更多的只是开阔眼界

2.偏特化

就是专门对一个类型去进行特殊的处理,毕竟template会给生成所有的类型相同的操作,但是有时候我们需要对特定的几个类型去处理,于是就有了特化和偏特化

3.局部类

一直被忽略的C++的语法,可以直接在类或者函数里面定义类,不过一直被忽视就对了,感觉这个还是挺有意思的

4.常数映射为型别:

template <int v>

struct Int2Type

{

enum

{

value = v;

}

}

这样的话,每次用不同的数字去实例化Int2Type,都是不同的类型

书中举了个反例

 1 <class T,bool flag>
 2 class myclass
 3 {
 4      void DoSomething ()
 5     {
 6           if(flag )
 7          {
 8               T *new_obj = p_old_obj-> clone();
 9          }
10           else
11          {
12               T *new_obj = new T(p_olb_obj );
13          }
14     }
15 };

上面的程序有两个问题

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,-1);
}

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 [2];
    };

     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

在前面的文章已经说过了

http://www.cnblogs.com/linyilong3/p/3379433.html.

总的来说,要理解这些技巧,需要理解几点:

1.模板的特化

2.编译器是通过寻找最合适的匹配选项来匹配选择实例化的类型

时间: 2024-11-08 20:25:35

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

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

PowerBuilder编程新思维3:适配(三层架构与GraphQL) PB在富客户端时代,是一线开发工具.随着网络发展,主流架构演进到三层架构的时代,PB拿不出有力的三层架构,已经明显力不从心,市场份额也江河日下.今天我们来细数一下PB的三层架构方式及其改进方法. PB三层架构方式一:EAServer 这是PB官方首推的三层架构,但是用三句可以总结,无感的体验,无奈的价格,无语的速度. 事实上除了EAServer这个选择,可以自己开发服务端,比如topwiz公司的PBNIServ 使用BPNI

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

<第二部分 Outside> PowerBuilder编程新思维4:钩挂(界面美化与DirectUI) PB的界面由于其封闭性,一直以来都是最大的弱项.自PB9.0开放了PBNI接口后,开始流行起来一些界面美化方案.目前来看,共分三类. PB界面美化方案一:Canvas自绘 PBNI接口允许创建自绘组件,开源软件Kodigo创造了Canvas组件,允许PB代码自绘组件界面,由此开创了Canvas自绘方案.当前比较流行的组件库有: 一.Kodigo 二.AdvancedGUI 三.PowerFr

如何绘制思维导图?分享产品上新思维导图模板及绘制技巧

当今企业激烈竞争的环境下,大多数企业面临着产品生命周期越来越短的压力.企业要在同行业中保持竞争力并能够占有市场份额,就必须不断地开发出新产品,并快速推向市场,满足多变的市场需求.一个新的产品上新之前要经过重重分析才能将产品的极限发挥出来,得到双赢的趋势,下面是分享的产品上新生物模板及绘制技巧,希望可以帮助到大家! 绘制技巧: 1.打开画图工具,点击页面上方[模板库]在跳转的页面有很多的模板: 2.在上方搜索栏目中输入模板关键词,这时在下方栏目中将出现对应的模板: 3.点击[在线编辑]进入在线绘制

提升编程能力的11个技巧

提升编程能力的11个技巧 1.首先仔细分析问题 2.接着好好想想如何解决这个问题 3.收集整理所有需求 花点时间将最终产品要实现的目标写下来,并且明确哪些是我们的目标用户群.如果这一步能做好的话,将会给后面节约大量的时间,正所谓磨刀不误砍柴工. 4.写一个全面的实施计划(或模型) 如果是个小项目,这一步出来的可能只是一个基本的流程或者一个简单的等式. 如果是个比较大的项目,这一步有助于我们将它切割成几个模块,然后再按下面的问题思考: ●各个模块需要执行什么任务 ●模块之间如何传递数据 ●如何调用

364家机构共办2017数博会,三大新思维指引新经济之战

2017年5月28日,为期四天的2017数博会落幕.在这四天里,来自美国.德国.英国.日本.俄罗斯.印度等20多个国家和地区,200多个城市近千家企业界代表和5万多名观展人员齐聚贵阳,围绕主题"数字引领经济新增长"展开交流,积极探索大数据发展未来. 本届数博会的"大"数据 在本届数博会最后一天的2017国际大数据产业博览成果新闻发布会上,组委会公布了一系列数据:据初步统计,本届数博会共对接企业1479家,其中500强企业112家,达成签约意向项目235个,意向金额2

《英语语法新思维初级教程》学习笔记(二)名词

参考资料: 1. <英语语法新思维初级教程> ? 知识点 ▼ 名词是用来表示人.事物.地点以及抽象事物的名称. ▼ 名词通常分为两大类:专有名词(proper noun)和普通名词(common noun). ▼ 专有名词表示特定的人.物.机构或场所等的名词(首字母须大写).如:Paris,the United States和Bill Gates等. ▼ 普通名词又分为:可数名词(countable noun)和不可数名词(uncountable noun)两类. ▼ 可数名词 = 个体名词

【Unity编程】Unity中关于四元数的API详解

Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计算Unity旋转.它们计算紧凑高效,不受万向节锁的困扰,并且可以很方便快速地进行球面插值. Unity内部使用四元数来表示所有的旋转. Quaternion是基于复数,并不容易直观地理解. 不过你几乎不需要访问或修改单个四元数参数(x,y,z,w); 大多数情况下,你只需要获取和使用现有的旋转(例如来自"Transform"),或者用四元数来构造新的旋转(例如,在两次旋转之间平滑插入). 大

《英语语法新思维初级教程》学习笔记(三)冠词

参考资料: 1. <英语语法新思维初级教程> 2. 英语国际英标表 ? 知识点 ▼ 限定词的是对名词起限定作用的各类词的总称,具体作用有限定名词所指的范围,对名词起泛指或特指.定量或或不定量等限定修饰. ▼ 冠词属于限定词(determiner),对名词起修饰作用.英语中的冠词由三个,其中两个是不定冠词a和an,一个是定冠词the(也可以认为它也是两个,同型不同音). out of the question // 不可能 out of question // 毫无疑问 ▼ the在辅音前读[ð

《C++设计新思维》勘误,附C++14新解法

勘误: 原书(中文版)3.13节,65-69页中GenScatterHierarchy以及FieldHelper均存在问题,当TypeList中类型有重复时,无法通过编译(原因在于"二义性基类"). 书中出现的二义性问题,可以用一小段代码演示一下: class A{}; class B:public A{}; class C:public A,public B{}; void test() { C c; A& cf =c;//wrong,don't try this at ho