书名: | 《自动化C++程序设计》 |
作者: | 熊春雷 |
网站: | http://www.autodev.net |
Blog: | http://blog.csdn.net/pandaxcl |
EMail: | pandaxcl@163.com |
昵称: | pandaxcl,开心 |
QQ: | 56637059 |
MSN: | pandaxcl@163.com |
版本: | 0.01 于2007/09/25 |
目标: | 所有C++爱好者 |
版权: | 本文的版权归熊春雷所有 |
代码库: | autocxx(在论坛下载) |
Warning
-
本文由熊春雷所写,绝对保证原创,在此特别严肃声明。本人简介:熊春 雷,男,1980年出生于湖北钟祥;七岁随父迁往宜昌开始学生生涯,小学和初中在 湖北宜昌樟村坪镇职工子弟学校就读;1996年考上宜昌县高中,开始三年的高中生 活;1999-2003就读于湖北大学物理系;2003-2006就读于武汉大学物理系。现就职 于盛大网络:)
-
绝对不能容忍他人说本文为他所写以及其他的侵权行为。一旦发现,一定 尽本人最大的能力以法律的形式严追到底,决不妥协。
-
引用本文,要保证本文的完整性,不可以删除此处的声明,并且务必注明出处。
Tip
-
本文编写的所有代码可以用于任何用途(包括商业用途)。
-
用于商业用途的需要在最后发布的软件中声明借鉴了本文的思想。具体事 宜可以协商解决,(代码决不收取任何费用)。
-
其他事项可以和我联系,包括技术讨论等等:)或者直接登陆网站论坛: http://www.autodev.net
Note
-
本文受到了《C++设计新思维》和《产生式编程》两本书的影响,同时也查阅了大 量的资料,从Loki库和Boost库中也吸收了不少营养,特此感谢之。
-
本文由于处于原创阶段,难免会出现各种各样的错误。代码出现错误的可能性非常 小(本来想说为零的),因为文档和代码是严格同步的,这是由VST文本的include 所保证的,代码都是测试成功之后才发布的。
-
本文所编写的代码,经过了VC2005编译器和g++编译器的测试,并且都通过了。
-
本文还没有彻底完成,算是一个初级版本,未来还将继续完善。暂时发布出来是为 了预知读者群有多少,读者越多,我的成就感越强,写作的时候也会更有动力:)
-
本文还会继续完善,欢迎各位读者的批评指正,也接受各种各样的建议,在权衡之 后以决定是否加入本书。
-
本书还没有最终完成,还会不断的进行完善,更新之后的内容将会发表于我的 网站或我的博客。所以还需要读者多多关心本文的进展:)
Contents
分析C++类层次
在编译期能够侦测某个类型是否派生自某个基类类型在编译期进行类型分类是非常有用的 。 通常这种能力还可以被扩充,用于侦测基类类型是否是某个模版类型。下面就分别讨论 这些 情况。
template<class Base,class Derived>struct is_kind_of
{
static Derived makeDerived();// 避免Derived的默认构造函数是私有的情况
static kind<1> test(...);// 匹配所有类型
static kind<2> test(const Base&);// 仅仅只是匹配Base类型或者是Base类型的派生类型
typedef n<sizeof(test(makeDerived()))==sizeof(kind<2>)> type;// 真正的判断来自于这里
};
上面的is_kind_of模版类采用了下面的C++技巧:
-
省略号(...)作为函数参数可以接受任意数量的任何类型
-
默认转型功能(派生类向基类转型)
-
sizeof静态测试函数返回值类型大小
-
C++函数重载函数匹配过程
下面是判断类型是否派生自指定基类类型的测试用例:
class Base1{};
class Base2{};
class Derived1:public Base1{};
class Derived2:public Base1,public Base2{};
class Other{};
static_assert_same<n<1>,is_kind_of<Base1,Derived1>::type>();// Derived1类派生自Base1类
static_assert_same<n<0>,is_kind_of<Base2,Derived1>::type>();// Derived1类不是派生自Base2类
static_assert_same<n<1>,is_kind_of<Base1,Derived2>::type>();// Derived2类派生自Base1类
static_assert_same<n<1>,is_kind_of<Base2,Derived2>::type>();// Derived2类派生自Base2类
static_assert_same<n<0>,is_kind_of<Base1,Other>::type>();// Other类不是派生自Base1类
static_assert_same<n<0>,is_kind_of<Base2,Other>::type>();// Other类不是派生自Base2类
从上面的测试代码可以看出,C++能够在编译期自动识别类型的继承关系,并且这种方法还 可 以用来判断一系列的指定类型关系,例如:判断是否是p类型,是否是p空类型, 是否 是只有一个元素的p类型等等,见下面的示例代码:
template<class x>struct trait
{
static x makex();
static kind<1> test(...);// 匹配所有类型
static kind<2> test(p<>);// 判断是否是p空类型
template<class H>static kind<3> test(p<H,nil>);// 判断是否是只有一个元素的p类型
template<class H,class T>static kind<4> test(p<H,T>);// 判断是否是有多于一个元素的p类型
enum{
is_other=sizeof(test(makex()))==sizeof(kind<1>),
is_empty_pair=sizeof(test(makex()))==sizeof(kind<2>),
is_pair_1_element=sizeof(test(makex()))==sizeof(kind<3>),
is_pair_more_element=sizeof(test(makex()))==sizeof(kind<4>)
};
};
下面就是上面的trait模版类的测试用例:
typedef p<> PS0;
typedef p<int> PS1;
typedef p<int,p<char> > PS2;
typedef p<int,p<char,p<long> > > PS3;
static_assert<trait<int>::is_other==true>();
static_assert<trait<int>::is_empty_pair==false>();
static_assert<trait<int>::is_pair_1_element==false>();
static_assert<trait<int>::is_pair_more_element==false>();
static_assert<trait<PS0>::is_other==false>();
static_assert<trait<PS0>::is_empty_pair==true>();
static_assert<trait<PS0>::is_pair_1_element==false>();
static_assert<trait<PS0>::is_pair_more_element==false>();
static_assert<trait<PS1>::is_other==false>();
static_assert<trait<PS1>::is_empty_pair==false>();
static_assert<trait<PS1>::is_pair_1_element==true>();
static_assert<trait<PS1>::is_pair_more_element==false>();
static_assert<trait<PS2>::is_other==false>();
static_assert<trait<PS2>::is_empty_pair==false>();
static_assert<trait<PS2>::is_pair_1_element==false>();
static_assert<trait<PS2>::is_pair_more_element==true>();
static_assert<trait<PS3>::is_other==false>();
static_assert<trait<PS3>::is_empty_pair==false>();
static_assert<trait<PS3>::is_pair_1_element==false>();
static_assert<trait<PS3>::is_pair_more_element==true>();
从上面的测试用例可以看出,通过这种C++静态测试技巧可以实现大量的类型判断,从而可 以 充分利用这种类型判断能力针对不同的类型进行不同的操作,以完成大量的配置自动化 功能。
Tip
-
上面的类型侦测技术还存在一个副作用,就是存在派生类型向基类类型转型的隐含转
-
换,稍有 不慎就会忽略这种转换。其实前面章节中的静态选择机制就是完全类 型匹
-
配机制,这种机制不存在隐式转型的能力,也就成为了精确类型分类了。具体什么时
-
候使 用什么类型侦测则由具体的需求来决定了。