网页功能: 加入收藏 设为首页 网站搜索  
泛型编程组件
发表日期:2007-03-28作者:[转贴] 出处:  

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

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

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

1。编译期断言

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

#define STATIC_CHECK(expr, msg) \
    { CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } 

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

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


2。编译期转换检测

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

template <class T, class U>
struct Conversion
{
typedef ConversionHelper<T, U> H;
enum { exists = sizeof(typename H::Small) == sizeof(H::Test(H::MakeT())) };
enum { exists2Way = exists && Conversion<U, T>::exists };
enum { sameType = false };
};
    
template <class T>
struct Conversion<T, T>    
{
enum { exists = 1, exists2Way = 1,sameType = 1 };
};
    
template <class T>
struct Conversion<void, T>    
{
        enum { exists = 1, exists2Way = 0,sameType = 0 };
};
    
template <class T>
struct Conversion<T, void>    
{
enum { exists = 1, exists2Way = 0,sameType = 0 };
};
    
template <>
class Conversion<void, void>    
{
public:
enum { exists = 1, exists2Way = 1,sameType = 1 };
};    

#define SUPERSUBCLASS(T, U) \
    (Conversion<const U*, const T*>::exists && \
    !Conversion<const T*, const void*>::sameType)

#define SUPERSUBCLASS_STRICT(T, U) \
    (SUPERSUBCLASS(T, U) && \
    !Conversion<const T, const U>::sameType)

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

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

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


3。编译期选择

实现:
template <bool flag, typename T, typename U>
struct Select
{
typedef T Result;
};
template <typename T, typename U>
struct Select<false, T, U>
{
typedef U Result;
};

原理:
模板偏特化

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

template<bool b>
class C : public Select<b, A, B> { };


4。编译期多态

实现:
template<class T>
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<T*>(this); }
};

原理:
模板的迭代编译

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

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

template<template<class>class T1, template<class>class T2>
class C_Impl : public T1<C_Impl>, public public T2<C_Impl> { };

typedef C_Impl<A, B> C;


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

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

struct NullType { };
struct EmptyType { };

//下面是操作Typelist的类

template <class TList> struct Length;
template <class TList, unsigned int index> struct TypeAt;
template <class TList, unsigned int index,typename DefaultType = NullType> struct TypeAtNonStrict;
template <class TList, class T> struct IndexOf;
template <class TList, class T> struct Append;
template <class TList, class T> struct Erase;
template <class TList, class T> struct EraseAll;
template <class TList> struct NoDuplicates;
template <class TList, class T, class U> struct Replace;
template <class TList, class T, class U> struct ReplaceAll;
template <class TList> struct Reverse;
template <class TList, class T> struct MostDerived;
template <class TList> struct DerivedToFront;

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

template <class TList, template <class> class Unit>
class GenScatterHierarchy;
     
template <class T1, class T2, template <class> class Unit>
class GenScatterHierarchy<Typelist<T1, T2>, Unit>
        : public GenScatterHierarchy<T1, Unit>
        , public GenScatterHierarchy<T2, Unit>
{
public:
        typedef Typelist<T1, T2> TList;
        typedef GenScatterHierarchy<T1, Unit> LeftBase;
        typedef GenScatterHierarchy<T2, Unit> RightBase;
        template <typename T> struct Rebind
        {
            typedef Unit<T> Result;
        };
};
     
template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType>
{
        typedef Unit<AtomicType> LeftBase;
        template <typename T> struct Rebind
        {
            typedef Unit<T> Result;
        };
};
    
template <template <class> class Unit>
class GenScatterHierarchy<NullType, Unit>
{
        template <typename T> struct Rebind
        {
            typedef Unit<T> Result;
        };
};


template
<
        class TList,
        template <class AtomicType, class Base> class Unit,
        class Root = EmptyType
>
class GenLinearHierarchy;
    
template
<
        class T1,
        class T2,
        template <class, class> class Unit,
        class Root
>
class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
        : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> > { };

template
<
        class T,
        template <class, class> class Unit,
        class Root
>
class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
        : public Unit<T, Root>  { };


template <int i, class H>
typename FieldHelper<H, i>::ResultType& Field(H& obj); 

原理:
metaprogram,也就是模板递归,模板偏特化。

使用:
使用Loki里提供的宏,Loki提供了50个宏

运用1,实现Tuple:

template <class T>
struct TupleUnit
{
        T value_;
        operator T&() { return value_; }
        operator const T&() const { return value_; }
};

template <class TList>
struct Tuple : public GenScatterHierarchy<TList, TupleUnit> { };

class A { };
class B { };
class C { };
class D { };

typedef Tuple<TYPELIST_4(A, B, C, D)> TupleClass;

TupleClass obj;

B& b = Field<1>(obj);

运用2,实现一个抽象工厂:

namespace Noir_Impl
{
template<class P>
struct CAF_Product { P* Create_Impl() { return new P; } };

template<class CProductList>
class CAF_AbstractFactory : public Loki::GenScatterHierarchy< CProductList, CAF_Product > { };
};

template<class IProductList, class CProductList>
struct Simple_AbstractFactory : public IProductList, private Noir_Impl::CAF_AbstractFactory< CProductList >
{
template<class IP> IP* Create()
{
typedef TypeAt< CProductList, IndexOf< IProductList, IP >::value > CP;
return CP::Create_Impl();
}
};

class IA { };
class IB { };
class IC { };
class ID { };

class A : public IA { };
class B : public IB { };
class C : public IC { };
class D : public ID { };

typedef Simple_AbstractFactory< TYPELIST_4(IA, IB, IC, ID), TYPELIST_4(A, B, C, D) > MyAF;

MyAf factory;

IA* pA = factory.Create<A>();
IB* pB = factory.Create<B>();
IC* pC = factory.Create<C>();
ID* pD = factory.Create<D>();

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 泛型编程组件
本类热点文章
  智能指针的标准之争:Boost vs. Loki
  创建模块化游戏 I(翻译)(Creating M..
  C++基本功和 Design Pattern系列(6) pu..
  C++基本功和 Design Pattern系列(11) E..
  网络在线游戏开发心得(服务器端、Java)
  用3D方法实现2D斜视角地图
  C++基本功和 Design Pattern系列(8) in..
  物品管理系统
  C++的学习感想
  C++基本功和 Design Pattern系列(10) B..
  解析boost
  C++基本功和 Design Pattern系列(9) vi..
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00412