Loki库读解四:HierarchyGenerators.h读注
这中间的每一行代码都是懂的,使用它的例子也看过了,可还是没明白应该怎样使用这东西。还望有人能答了。
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
// The author or Addison-Welsey Longman make no representations about the
// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: March 05, 2001
#ifndef HIERARCHYGENERATORS_INC_
#define HIERARCHYGENERATORS_INC_
#include "Typelist.h"
#include "TypeTraits.h"
#include "EmptyType.h"
namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
// class template GenScatterHierarchy
// Generates a scattered hierarchy starting from a typelist and a template
// Invocation (TList is a typelist, Model is a template of one arg):
// GenScatterHierarchy<TList, Model>
// The generated class inherits all classes generated by instantiating the
// template 'Model' with the types contained in TList
////////////////////////////////////////////////////////////////////////////////
//WQ注:从TypeList中的所有类型进行多继承,实现上是包容型派生(Unit<T>),类型间去耦合,所以没有菱形缺陷。
如果list中有类型重复,或再有一个TypeList(树状)则为自找麻烦。
template <class TList, template <class> class Unit>
class GenScatterHierarchy;
//WQ注:前置申明,参数和实现时并不一致,是为了表明设计意图的。
template <class T1, class T2, template <class> class Unit>
class GenScatterHierarchy<Typelist<T1, T2>, Unit> //WQ注:偏特化。Loki库中,经常可见到:偏特化才是主导作用,模板本体反而是偏特化的特例。
: public GenScatterHierarchy<T1, Unit>
, public GenScatterHierarchy<T2, Unit>
//WQ注:如果用TypeList<T1,T2>::Head、Tail来代替此两行中的T1和T2就比较清楚了。
{
public:
typedef Typelist<T1, T2> TList;
typedef GenScatterHierarchy<T1, Unit> LeftBase;
typedef GenScatterHierarchy<T2, Unit> RightBase;
//WQ注:和TypeList的Head、Tail类似。
template <typename T> struct Rebind
{
typedef Unit<T> Result;
};//WQ注:它没有要求T处于TypeList中。但按其它代码推测,T必须处于TypeList中。用Loki库的其它部件,是可以进行这样的编译期检查的。
//WQ注:还要注意“派生类同名成员掩盖基类版本”这个细节。
};
template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType>
//WQ注:这是模板的实现体,却只用来实现传统类类型的情况的。
{
typedef Unit<AtomicType> LeftBase;
template <typename T> struct Rebind
{
typedef Unit<T> Result;
};
};
template <template <class> class Unit>
class GenScatterHierarchy<NullType, Unit>
//WQ注:别忘了这个边界点。
{
template <typename T> struct Rebind
{
typedef Unit<T> Result;
};
};
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
// T is a type in the typelist used to generate H):
// Field<T>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
////////////////////////////////////////////////////////////////////////////////
//WQ注:注意上面的说明,可别用错了。
template <class T, class H>
typename H::Rebind<T>::Result& Field(H& obj)
{//WQ注:T处于TypeList中时,Unit<T>肯定是H的基类,能自动进行向上类型映射。再加上TupleUnit的operator T&(),就最终实现了H到T的类型转换。
return obj;
}
template <class T, class H>
const typename H::Rebind<T>::Result& Field(const H& obj)
{
return obj;
}
////////////////////////////////////////////////////////////////////////////////
// function template TupleUnit
// The building block of tuples
////////////////////////////////////////////////////////////////////////////////
//WQ注:本身只是一个简单的包容器,其偏特化才更有用。
template <class T>
struct TupleUnit
{
T value_;
operator T&() { return value_; }
operator const T&() const { return value_; }
};
////////////////////////////////////////////////////////////////////////////////
// class template Tuple
// Implements a tuple class that holds a number of values and provides field
// access to them via the Field function (below)
////////////////////////////////////////////////////////////////////////////////
template <class TList>
struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
{
};
//WQ注:实现了如下图的结构!
////////////////////////////////////////////////////////////////////////////////
// helper class template FieldHelper
// See Field below
////////////////////////////////////////////////////////////////////////////////
//WQ注:I超范围时,会发生编译错误。可参看TypeList::TypeAt()的实现。
template <class H, unsigned int i> struct FieldHelper;
template <class H>
struct FieldHelper<H, 0>
//特例化0,是为了判断RightBase还是LeftBase
{
typedef typename H::TList::Head ElementType;
typedef typename H::Rebind<ElementType>::Result UnitType;
enum
{
isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
//WQ注:此句判断了H是不是用TupleUnit生成的,因为本类依赖于H到T一定要有转换关系。如果使用用户自定义的Unit类,而它又没提供此功能,可就……。
isConst = TypeTraits<H>::isConst
//WQ注:Loki对类型上的萃取能力也达到极至,在TypeTraits.h中,代码比较简单,几乎一看就明白,只是感叹“只有想不到的,没有做不到的”。
};
typedef const typename H::LeftBase ConstLeftBase;
typedef typename Select<isConst, ConstLeftBase,
typename H::LeftBase>::Result LeftBase;
typedef typename Select<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
//WQ注:为了减少对用户自定义operator T&()的调用,因为C++规定“自定义的类型转换只能隐式调用一次”,所以要尽可能予以保留。
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj)
{
LeftBase& leftBase = obj;//WQ注:显式完成类型转换。理由还上同。
return leftBase;
}
};
template <class H, unsigned int i>
struct FieldHelper
{
typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
//WQ注:这些信息可以直接获取,所有不进行递归了。
typedef typename H::Rebind<ElementType>::Result UnitType;
enum
{
isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isConst = TypeTraits<H>::isConst
};
typedef const typename H::RightBase ConstRightBase;
typedef typename Select<isConst, ConstRightBase,
typename H::RightBase>::Result RightBase;
typedef typename Select<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj)
{
RightBase& rightBase = obj;
return FieldHelper<RightBase, i - 1>::Do(rightBase);
//WQ注:类型转换时,可没法直接进行,只好递归进行了。
}
};
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
// i is the index of a type in the typelist used to generate H):
// Field<i>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
// and T is the i-th type in the typelist
////////////////////////////////////////////////////////////////////////////////
//WQ注:转换到第I个基类,注意上面的说明。
template <int i, class H>
typename FieldHelper<H, i>::ResultType&
Field(H& obj)
{
return FieldHelper<H, i>::Do(obj);
}
// template <int i, class H>
// const typename FieldHelper<H, i>::ResultType&
// Field(const H& obj)
// {
// return FieldHelper<H, i>::Do(obj);
// }
////////////////////////////////////////////////////////////////////////////////
// class template GenLinearHierarchy
// Generates a linear hierarchy starting from a typelist and a template
// Invocation (TList is a typelist, Model is a template of two args):
// GenScatterHierarchy<TList, Model>
////////////////////////////////////////////////////////////////////////////////
//WQ注:注意申明中的参数名称起的暗示作用!
template
<
class TList,//WQ注:必须传递一个TypeList。
template <class AtomicType, class Base> class Unit,//WQ注:Unit必须是使用(理论上是指不得比使用关系更弱,所有,继承亦可)第一个参数,并从第二个参数进行继承。可在abstractfactory.h,PrototypefactoryUnit是其示范实现。
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> >
{
};
//WQ注:由于TypeList本身的递归关系,形式下图结构:
template
<
class T,
template <class, class> class Unit,
class Root
>
class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root> //WQ注:边界点
: public Unit<T, Root>
{
};
//WQ注:网上有人指出,基于完备性,应该增加<NullType, Unit, Root>的偏特化。但,这个类明确说明了,其接口是要求传入一个TypeList,所以此偏特化需求不在考虑之列。
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // HIERARCHYGENERATORS_INC_
本文地址:http://com.8s8s.com/it/it2193.htm