| 论坛注册| 加入收藏 | 设为首页| RSS
Google
您当前的位置:首页 > Linux频道 > Linux开发区 > 软件开发

C++自动化(模板元)编程基础与应用

时间:2006-06-16 11:29:29  来源:中国IT实验室  作者:Linux联盟收集
O旅嫖颐抢纯纯碈++里面的多继承现象和参数化继承现象:vDTLinux联盟
vDTLinux联盟
#endifvDTLinux联盟
vDTLinux联盟
#ifdef CODE_NOTEvDTLinux联盟
//多继承现象vDTLinux联盟
class Base1{};vDTLinux联盟
class Base2{};vDTLinux联盟
class Base3{};vDTLinux联盟
class Derived:public Base1,public Base2,public Base3{};vDTLinux联盟
//模板参数化继承现象:vDTLinux联盟
template Base{};vDTLinux联盟
class Derived:public Base,public Base,public Base{};vDTLinux联盟
#endif//CODE_NOTEvDTLinux联盟
vDTLinux联盟
#if 0vDTLinux联盟
vDTLinux联盟
从上面的多继承和参数化的多继承我们可以得到什么灵感呢?如果没有,那么再考虑vDTLinux联盟
一下上一章中所介绍的类型串类型,^_^这时候有没有灵感了呢?呵呵,实际上上面的代码vDTLinux联盟
中的参数化多继承的基类就是一个类型遍历过程,针对每一个类型,用Base包裹住每一个vDTLinux联盟
类型并作为Derived类的基类,这样就可以生成一个自己定制的类了。如果能够使这个过程vDTLinux联盟
自动化,那么我们就可以认为代码被自动生成了。vDTLinux联盟
vDTLinux联盟
现在考虑一下上面的自动化过程所需要的输入和输出分别是什么:vDTLinux联盟
vDTLinux联盟
输入:一个cons类型串记录所有的需要的类型,一个包裹模板类vDTLinux联盟
vDTLinux联盟
输出:生成一个由所有的cons类型串中的类型作为模板参数的包裹类作为基类的类vDTLinux联盟
vDTLinux联盟
这样如果在包裹类里面定义了一个模板参数类型的成员变量,那么生成的类中就有所vDTLinux联盟
有的这些类型的变量,也就是说这些变量都成了生成的类的成员变量。vDTLinux联盟
vDTLinux联盟
好了,说到这里,我们来看看具体的实现过程是怎样的:vDTLinux联盟
vDTLinux联盟
#endifvDTLinux联盟
vDTLinux联盟
#ifdef CODE_NOTEvDTLinux联盟
//下面是实现代码自动生成的模板元函数,主要参考了Loki的代码vDTLinux联盟
//为了撤销和重做库的独立性,将该功能从Loki库中提取出来vDTLinux联盟
templateclass Unit>vDTLinux联盟
struct scatter : public UnitvDTLinux联盟
{vDTLinux联盟
};vDTLinux联盟
templateclass Unit>vDTLinux联盟
struct scatter,Unit>vDTLinux联盟
: public scattervDTLinux联盟
, public scattervDTLinux联盟
{vDTLinux联盟
typedef cons cons_type;vDTLinux联盟
};vDTLinux联盟
//下面的null_type参看前一章中的代码vDTLinux联盟
templateclass Unit>vDTLinux联盟
struct scattervDTLinux联盟
{vDTLinux联盟
};vDTLinux联盟
#endif//CODE_NOTEvDTLinux联盟
vDTLinux联盟
#if 0vDTLinux联盟
vDTLinux联盟
在给出具体的测试代码之前还需要做一件事情,那就是将上面的scatter代码
放到meta.h文件中vDTLinux联盟
便于代码组织,也是为了使用前面的类型null_type。关于本文所使用的meta.h
文件仅仅只是在前一vDTLinux联盟
章的meta.h文件的末尾追加了上面的scatter元函数,详细的内容在本文的
最后给出。下面看看如何vDTLinux联盟
使用上面的模板元函数scatter来自动生成代码,见CODE1:vDTLinux联盟
vDTLinux联盟
#endifvDTLinux联盟
vDTLinux联盟
#ifdef CODE1vDTLinux联盟
//下面的是测试代码vDTLinux联盟
#include vDTLinux联盟
#include "meta.h"//这里的meta.h文件内容比上一章的内容多了一些,见本文末尾vDTLinux联盟
namespace xcl=pandaxcl;vDTLinux联盟
template struct UnitvDTLinux联盟
{vDTLinux联盟
T _value;//成员变量vDTLinux联盟
};vDTLinux联盟
template vDTLinux联盟
class Class:public xcl::scattervDTLinux联盟
{//注意这里没有任何的成员函数vDTLinux联盟
};vDTLinux联盟
int main()vDTLinux联盟
{vDTLinux联盟
typedef xcl::consvDTLinux联盟
xcl::consvDTLinux联盟
  xcl::consvDTLinux联盟
xcl::consvDTLinux联盟
xcl::consvDTLinux联盟
              xcl::consvDTLinux联盟
xcl::null_type> > > > > >CONS;vDTLinux联盟
Class var;//声明一个类型变量vDTLinux联盟
std::cout << sizeof(var) << std::endl;vDTLinux联盟
std::cout << sizeof(Class) << std::endl;vDTLinux联盟
//下面的这些代码的成功编译标志着上面的过程确确实实产生了代码vDTLinux联盟
static_cast&>(var)._value = 1;vDTLinux联盟
static_cast&>(var)._value = 1;vDTLinux联盟
static_cast&>(var)._value = 1;vDTLinux联盟
static_cast&>(var)._value = 1;vDTLinux联盟
static_cast&>(var)._value = 1;vDTLinux联盟
static_cast&>(var)._value = 1;vDTLinux联盟
return 0;vDTLinux联盟
}vDTLinux联盟
#endif//CODE1vDTLinux联盟
//////////////////////////////////////////////////////vDTLinux联盟
//该程序的运行结果如下:vDTLinux联盟
/*********************************************************vDTLinux联盟
48vDTLinux联盟
48vDTLinux联盟
************************************************************/vDTLinux联盟
///////////////////////////////////////////////////////////vDTLinux联盟
#if 0vDTLinux联盟
vDTLinux联盟
从上面的程序中我们可以看出代码生成过程确实是成功完成了,但是我们还应该注意vDTLinux联盟
到上面的类型串中的的类型是绝对不允许重复的,否则后面的static_cast静态转型将会出vDTLinux联盟
现模棱两可的情况。这一点在Loki库已经成功的解决了,但是在我们将要讨论的撤销和重vDTLinux联盟
做库中并不会出现这种情况,所以为了使得代码尽可能的简单,我们就采用最简单的方式vDTLinux联盟
。因为简单的就是最好的嘛!实际上通过这种简单的类型串规定再通过外覆一个包裹层同vDTLinux联盟
样可以解决类型重复的问题。vDTLinux联盟
vDTLinux联盟
上面的生成的类中已经具备了成员变量,但这仅仅相当于实现了一种结构体,离真正vDTLinux联盟
的使用还有一段距离。因为生成的类中没有成员函数,只有在有了成员函数之后才可以真vDTLinux联盟
正的实用化,这就是前面的章节中介绍的cons类型和静态LOOP循环的联合使用发挥威力的vDTLinux联盟
时候了。好,首先让我们来看一个具体的问题:vDTLinux联盟
vDTLinux联盟
考虑下面的自动生成的类:vDTLinux联盟
vDTLinux联盟
#endifvDTLinux联盟
#ifdef CODE_NOTEvDTLinux联盟
template struct Unit:public std::vector{};vDTLinux联盟
template class Class : public xcl::scattervDTLinux联盟
{vDTLinux联盟
public:vDTLinux联盟
//仔细考虑一下下面的这个成员函数应该如何实现?vDTLinux联盟
//该成员函数就是为了输出自动生成的类中的所有的成员变量vDTLinux联盟
//(std::vector容器成员变量)的内容。vDTLinux联盟
void print(){}vDTLinux联盟
};vDTLinux联盟
#endif//CODE_NOTEvDTLinux联盟
#if 0vDTLinux联盟
vDTLinux联盟
从上面自动生成的类来说,为了能够自动的根据类型将所有的成员变量的内容都vDTLinux联盟
进行输出,需要写一个print成员函数,这个成员函数能够根据类型串的不同而自动的vDTLinux联盟
生成相应的处理代码,关于这一点的实现参见代码CODE2:vDTLinux联盟
vDTLinux联盟
#endifvDTLinux联盟
#ifdef CODE2vDTLinux联盟
#include vDTLinux联盟
#include vDTLinux联盟
#include vDTLinux联盟
#include vDTLinux联盟
#include vDTLinux联盟
#include "meta.h"//见本文末尾vDTLinux联盟
namespace xcl=pandaxcl;vDTLinux联盟
template struct Unit:public std::vector{};vDTLinux联盟
template class Class : public xcl::scattervDTLinux联盟
{vDTLinux联盟
template struct PRINTvDTLinux联盟
{vDTLinux联盟
templatevDTLinux联盟
static void execute(EnvironmentType&e)vDTLinux联盟
{vDTLinux联盟
//你的代码在这里编写vDTLinux联盟
typedef typename xcl::type::result CT;vDTLinux联盟
Unit &v = static_cast&>(e);vDTLinux联盟
std::copy(v.begin(),v.end(),
std::ostream_iterator(std::cout," "));vDTLinux联盟
std::cout << std::endl;//用来分开不同类型的数据vDTLinux联盟
}vDTLinux联盟
};vDTLinux联盟
public:vDTLinux联盟
//下面是成员函数得实现vDTLinux联盟
void print()vDTLinux联盟
{vDTLinux联盟
//通过参数传递实现了静态代码和动态代码的连接vDTLinux联盟
xcl::LOOP<:length::value,1>::execute(*this);vDTLinux联盟
}vDTLinux联盟
};vDTLinux联盟
int main()vDTLinux联盟
{vDTLinux联盟
{//这是一个自动生成类的测试vDTLinux联盟
typedef xcl::consvDTLinux联盟
<:length  xcl::consvDTLinux联盟
xcl::consvDTLinux联盟
<:length      xcl::null_type> > > CONS;vDTLinux联盟
Class var;vDTLinux联盟
//在输出之前需要初始化var变量vDTLinux联盟
static_cast&>(var).push_back('A');vDTLinux联盟
static_cast&>(var).push_back('B');vDTLinux联盟
static_cast&>(var).push_back('C');vDTLinux联盟
vDTLinux联盟
static_cast&>(var).push_back(1);vDTLinux联盟
static_cast&>(var).push_back(2);vDTLinux联盟
static_cast&>(var).push_back(3);vDTLinux联盟
static_cast&>(var).push_back(4);vDTLinux联盟
vDTLinux联盟
static_cast&>(var).push_back(1.1);vDTLinux联盟
static_cast&>(var).push_back(2.2);vDTLinux联盟
static_cast&>(var).push_back(3.3);vDTLinux联盟
static_cast&>(var).push_back(4.4);vDTLinux联盟
//输出所有的成员变量的内容vDTLinux联盟
var.print();vDTLinux联盟
}vDTLinux联盟
{//这是另一个自动生成类的测试vDTLinux联盟
//修改了类型串之后不需要修改原来的print成员就可以实现所有的输出vDTLinux联盟
typedef std::complex COMPLEX;vDTLinux联盟
typedef xcl::consvDTLinux联盟
xcl::consvDTLinux联盟
<:length        xcl::cons<:string,
xcl::null_type> > > CONS;vDTLinux联盟
Class var;vDTLinux联盟
//在输出之前需要初始化var变量vDTLinux联盟
static_cast&>(var).push_back('A');vDTLinux联盟
static_cast&>(var).push_back('B');vDTLinux联盟
static_cast&>(var).push_back('C');vDTLinux联盟
vDTLinux联盟
static_cast&>(var).push_back(COMPLEX(1.1,0.1));vDTLinux联盟
static_cast&>(var).push_back(COMPLEX(2.2,0.2));vDTLinux联盟
static_cast&>(var).push_back(COMPLEX(3.3,0.3));vDTLinux联盟
static_cast&>(var).push_back(COMPLEX(4.4,0.4));vDTLinux联盟
vDTLinux联盟
static_cast<:string>&>(var).push_back("熊春雷");vDTLinux联盟
static_cast<:string>&>(var).push_back("熊猫");vDTLinux联盟
static_cast<:string>&>(var).push_back("国宝");vDTLinux联盟
static_cast<:string>&>(var).push_back("开心");vDTLinux联盟
static_cast<:string>&>(var).push_back("pandaxcl");vDTLinux联盟
//输出所有的成员变量的内容vDTLinux联盟
var.
 6/11   |‹ ‹‹ 4 5 6 7 8 9 ›› ›|

来顶一下
近回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
相关文章
    无相关信息
栏目更新
栏目热门