常数、类型到类型的映射
一、常数到类型的映射(Mapping Integral Constants to Types)
1 template <int N> 2 struct Int2Type { 3 enum { value = N }; 4 };
根据“不同的template 参数”出导出的类型是“不同的类型”,Int2Type 会根据参数的不同来产生不同的类型;
一般而言,符合下列两个条件便可使用IntToType:
有必要根据某个编译期常数调用一个或数个不同的函数;
有必要在编译期实施“分派”(dispatch);
下面是一个应用示例:
template <typename T, bool isProlymorphic> class NiftyContainer { private: void DoSomething(T* pObj, Int2Type<true>) { T* pNewObj = pObj->Clone(); // prolymorphic algorithm ... } void DoSomething(T* pObj, Int2Type<false>) { T* pNewObj = new T(*pObj); // nonprolymorphic algorithm ... } public: void DoSomething(T* pObj) { DoSomething(pObj, Int2Type<isProlymorphic>()); } };
二、类型到类型的映射(type-to-Type Mapping)
template 函数不能偏特化,这个映射可以帮助我模拟出类似的机制。Type2Type定义如下:
template <typename T> struct Type2Type { typedef T OriginalType; };
下面是一个应用示例:
class Widget; template <class T, class U> T* Create(const U& arg, Type2Type<T>) { return new T(arg); } template <class U> Widget* Create(const U& arg, Type2Type<Widget>) { return new Widget(arg, -1); }
三、类型选择(Type Selection)
假设我们需要vertor中存储T或T*, 当isProlymorphic 是存储T*,否则存储T
可以使用偏特化,第一种方法这样:
template<typename T, bool isPolymorphic> struct NiftyContainerValueTraits { typedef T* valueType; }; template<typename T> struct NiftyContainerValueTraits<T, false> { typedef T valueType; }; template <typename T, bool isPolymorphic> class NiftyContainer { typedef NiftyContainerValueTraits<T, isPolymorphic> Traits; typedef typename Traits::valueType valueType; };
第二种使用类型选择:
template <bool flag, typename T, typename U> struct TypeSelect { typedef T Result; }; template <typename T, typename U> struct TypeSelect<false, T, U> { typedef U Result; }; template <typename T, bool isPolymorphic> class NiftyContainer1 { typedef TypeSelect<isPolymorphic, T*, T>::Result valueType; };