泛型编程组件(转)

泛型编程组件
下面将介绍泛型编程的最重要的组件,他们是:
1。编译期断言
2。编译期转换检测
3。编译期选择
4。编译期多态
5。代码容器

再一次说,这是泛型里最重要的组件,值得你去理解和使用,他们的实现有很多版本,Boost和Loki都有实现,在认真比较以后,我认为Loki确实更加简单和强大,所以我选择Loki的代码进行示例,如果你有兴趣深入了解,请读《C++设计新思维》。

值得注意的是,为了便于理解,我把Loki的代码进行了适当修改。

1。编译期断言

实现:
template struct CompileTimeError;
template<> struct CompileTimeError {};

#define STATIC_CHECK(expr, msg)
{ CompileTimeError ERROR_##msg; (void)ERROR_##msg; }

原理:
利用template<> struct CompileTimeError并没有特化体,所以产生他的实例ERROR_##msg编译器就会报错。

使用:
const int i = 0;
STATIC_CHECK(i==0, "i因该等于0");


2。编译期转换检测

实现:
template
struct ConversionHelper
{
typedef char Small;
struct Big { char dummy[2]; };
static Big Test(...);
static Small Test(U);
static T MakeT();
};

template
struct Conversion
{
typedef ConversionHelper H;
enum { exists = sizeof(typename H::Small) == sizeof(H::Test(H::MakeT())) };
enum { exists2Way = exists && Conversion::exists };
enum { sameType = false };
};

template
struct Conversion
{
enum { exists = 1, exists2Way = 1,sameType = 1 };
};

template
struct Conversion
{
enum { exists = 1, exists2Way = 0,sameType = 0 };
};

template
struct Conversion
{
enum { exists = 1, exists2Way = 0,sameType = 0 };
};

template <>
class Conversion
{
public:
enum { exists = 1, exists2Way = 1,sameType = 1 };
};

#define SUPERSUBCLASS(T, U)
(Conversion::exists &&
!Conversion::sameType)

#define SUPERSUBCLASS_STRICT(T, U)
(SUPERSUBCLASS(T, U) &&
!Conversion::sameType)

原理:
利用函数的参数列表的型别推测机制得到编译器使用哪个函数,而函数返回型别,接着利用 sizeof()一定会在编译期求出值来获得返回型别的大小,依此来判断调用了哪个函数,然后在利用enum是编译期确定的常数,把sizeof()返回的值具体化出来。

使用:
class A { };
class B : public A { };

STATIC_CHECK( SUPERSUBCLASS(A, B), "A因该是B的基类");


3。编译期选择

实现:
template
struct Select
{
typedef T Result;
};
template
struct Select
{
typedef U Result;
};

原理:
模板偏特化

使用:
class A { };
class B { };

template
class C : public Select { };


4。编译期多态

实现:
template
class Relex
{
private:
Relex(const Relex&);
Relex& operator = (const Relex&);
public:
typedef T _HostType;
typedef T& _HostReference;
typedef T* _HostPointer;
public:
Relex() { }
T* GetHostPtr() { return reinterpret_cast(this); }
};

原理:
模板的迭代编译

使用:
template
struct A : Relex
{
void func1() { GetHostPtr()->func2(); }
};

template
struct B : Relex
{
void func2() { GetHostPtr()->func1(); }
};

templateclass T1, templateclass T2>
class C_Impl : public T1, public public T2 { };

typedef C_Impl C;



5。代码容器
这里的实现非常巨大,就不写了,你可以自己去看代码

实现:
template
struct Typelist //请想想STL里的list,非常象。这里的Tail又是一个Typelist,这样形成一个链
{
typedef T Head;
typedef U Tail;
};
//Typelist的头是Typelist,我们把NullType作为链的尾。

struct NullType { };
struct EmptyType { };

//下面是操作Typelist的类

template struct Length;
template struct TypeAt;
template struct TypeAtNonStrict;
template struct IndexOf;
template struct Append;
template struct Erase;
template struct EraseAll;
template struct NoDuplicates;
template struct Replace;
template struct ReplaceAll;
template struct Reverse;
template struct MostDerived;
template struct DerivedToFront;

//下面就是代码容器,典型的模板递归和模板偏特化的运用,请仔细看,其实很简单

template class Unit>
class GenScatterHierarchy;

template class Unit>
class GenScatterHierarchy, Unit>
: public GenScatterHierarchy
, public GenScatterHierarchy
{
public:
typedef Typelist TList;
typedef GenScatterHierarchy LeftBase;
typedef GenScatterHierarchy RightBase;
template struct Rebind
{
typedef Unit Result;
};
};

template class Unit>
class GenScatterHierarchy : public Unit
{
typedef Unit LeftBase;
template struct Rebind
{
typedef Unit Result;
};
};

template class Unit>
class GenScatterHierarchy
{
template struct Rebind
{
typedef Unit Result;
};
};


template
<
class TList,
template class Unit,
class Root = EmptyType
>
class GenLinearHierarchy;

template
<
class T1,
class T2,
template class Unit,
class Root
>
class GenLinearHierarchy, Unit, Root>
: public Unit< T1, GenL


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-126672/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10294527/viewspace-126672/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值