⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 typet.hpp

📁 C++ Templates 完全导引范例
💻 HPP
字号:
/* The following code example is taken from the book * "C++ Templates - The Complete Guide" * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002 * * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. */#ifndef TYPET_HPP#define TYPET_HPP// define IsFundaT<>/********************************** * type1.hpp: **********************************/// primary template: in general T is no fundamental typetemplate <typename T>class IsFundaT {  public:    enum { Yes = 0, No = 1};};// macro to specialize for fundamental types#define MK_FUNDA_TYPE(T)               \    template<> class IsFundaT<T> {     \      public:                          \        enum { Yes = 1, No = 0 };      \    };MK_FUNDA_TYPE(void)MK_FUNDA_TYPE(bool)MK_FUNDA_TYPE(char)MK_FUNDA_TYPE(signed char)MK_FUNDA_TYPE(unsigned char)MK_FUNDA_TYPE(wchar_t)MK_FUNDA_TYPE(signed short)MK_FUNDA_TYPE(unsigned short)MK_FUNDA_TYPE(signed int)MK_FUNDA_TYPE(unsigned int)MK_FUNDA_TYPE(signed long)MK_FUNDA_TYPE(unsigned long)#if LONGLONG_EXISTS  MK_FUNDA_TYPE(signed long long)  MK_FUNDA_TYPE(unsigned long long)#endif  // LONGLONG_EXISTSMK_FUNDA_TYPE(float)MK_FUNDA_TYPE(double)MK_FUNDA_TYPE(long double)#undef MK_FUNDA_TYPE/**** end of type1.hpp ****/// define primary template CompoundT<> (first version)//#include "type2.hpp"// define primary template CompoundT<> (second version)/********************************** * type6.hpp: **********************************/template<typename T>class IsFunctionT {  private:    typedef char One;    typedef struct { char a[2]; } Two;    template<typename U> static One test(...);    template<typename U> static Two test(U (*)[1]);  public:    enum { Yes = sizeof(IsFunctionT<T>::test<T>(0)) == 1 };    enum { No = !Yes };};template<typename T>class IsFunctionT<T&> {  public:    enum { Yes = 0 };    enum { No = !Yes };};template<>class IsFunctionT<void> {  public:    enum { Yes = 0 };    enum { No = !Yes };};template<>class IsFunctionT<void const> {  public:    enum { Yes = 0 };    enum { No = !Yes };};// same for void volatile and void const volatile//...template<typename T>class CompoundT {           // primary template  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0,           IsFuncT = IsFunctionT<T>::Yes,           IsPtrMemT = 0 };    typedef T BaseT;    typedef T BottomT;    typedef CompoundT<void> ClassT;};/**** end of type6.hpp ****/// define CompoundT<> specializations/********************************** * type3.hpp: **********************************/template<typename T>class CompoundT<T&> {       // partial specialization for references  public:    enum { IsPtrT = 0, IsRefT = 1, IsArrayT = 0,           IsFuncT = 0, IsPtrMemT = 0 };    typedef T BaseT;    typedef typename CompoundT<T>::BottomT BottomT;    typedef CompoundT<void> ClassT;};template<typename T>class CompoundT<T*> {       // partial specialization for pointers  public:    enum { IsPtrT = 1, IsRefT = 0, IsArrayT = 0,           IsFuncT = 0, IsPtrMemT = 0 };    typedef T BaseT;    typedef typename CompoundT<T>::BottomT BottomT;    typedef CompoundT<void> ClassT;};/**** end of type3.hpp ****//********************************** * type4.hpp: **********************************/#include <stddef.h>template<typename T, size_t N>class CompoundT <T[N]> {    // partial specialization for arrays  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1,           IsFuncT = 0, IsPtrMemT = 0 };    typedef T BaseT;    typedef typename CompoundT<T>::BottomT BottomT;    typedef CompoundT<void> ClassT;};template<typename T>class CompoundT <T[]> {    // partial specialization for empty arrays  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1,           IsFuncT = 0, IsPtrMemT = 0 };    typedef T BaseT;    typedef typename CompoundT<T>::BottomT BottomT;    typedef CompoundT<void> ClassT;};template<typename T, typename C>class CompoundT <T C::*> {  // partial specialization for pointer-to-members  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0,           IsFuncT = 0, IsPtrMemT = 1 };    typedef T BaseT;    typedef typename CompoundT<T>::BottomT BottomT;    typedef C ClassT;};/**** end of type4.hpp ****//********************************** * type5.hpp: **********************************/template<typename R>class CompoundT<R()> {  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0,           IsFuncT = 1, IsPtrMemT = 0 };    typedef R BaseT();    typedef R BottomT();    typedef CompoundT<void> ClassT;};template<typename R, typename P1>class CompoundT<R(P1)> {  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0,           IsFuncT = 1, IsPtrMemT = 0 };    typedef R BaseT(P1);    typedef R BottomT(P1);    typedef CompoundT<void> ClassT;};template<typename R, typename P1>class CompoundT<R(P1, ...)> {  public:    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0,           IsFuncT = 1, IsPtrMemT = 0 };    typedef R BaseT(P1);    typedef R BottomT(P1);    typedef CompoundT<void> ClassT;};//.../**** end of type5.hpp ****/// define IsEnumT<>/********************************** * type7.hpp: **********************************/struct SizeOverOne { char c[2]; };template<typename T,         bool convert_possible = !CompoundT<T>::IsFuncT &&                                 !CompoundT<T>::IsArrayT>class ConsumeUDC {  public:    operator T() const;};// conversion to function types is not possibletemplate <typename T>class ConsumeUDC<T, false> {};// conversion to void type is not possibletemplate <bool convert_possible>class ConsumeUDC<void, convert_possible> {};char enum_check(bool);char enum_check(char);char enum_check(signed char);char enum_check(unsigned char);char enum_check(wchar_t);char enum_check(signed short);char enum_check(unsigned short);char enum_check(signed int);char enum_check(unsigned int);char enum_check(signed long);char enum_check(unsigned long);#if LONGLONG_EXISTS  char enum_check(signed long long);  char enum_check(unsigned long long);#endif  // LONGLONG_EXISTS// avoid accidental conversions from float to intchar enum_check(float);char enum_check(double);char enum_check(long double);SizeOverOne enum_check(...);    // catch alltemplate<typename T>class IsEnumT {  public:    enum { Yes = IsFundaT<T>::No &&                 !CompoundT<T>::IsRefT &&                 !CompoundT<T>::IsPtrT &&                 !CompoundT<T>::IsPtrMemT &&                 sizeof(enum_check(ConsumeUDC<T>()))==1 };    enum { No = !Yes };};/**** end of type7.hpp ****/// define IsClassT<>/********************************** * type8.hpp: **********************************/template<typename T>class IsClassT {  public:    enum { Yes = IsFundaT<T>::No &&                 IsEnumT<T>::No &&                 !CompoundT<T>::IsPtrT &&                 !CompoundT<T>::IsRefT &&                 !CompoundT<T>::IsArrayT &&                 !CompoundT<T>::IsPtrMemT &&                 !CompoundT<T>::IsFuncT };    enum { No = !Yes };};/**** end of type8.hpp ****/// define template that handles all in one styletemplate <typename T>class TypeT {  public:    enum { IsFundaT  = IsFundaT<T>::Yes,           IsPtrT    = CompoundT<T>::IsPtrT,           IsRefT    = CompoundT<T>::IsRefT,           IsArrayT  = CompoundT<T>::IsArrayT,           IsFuncT   = CompoundT<T>::IsFuncT,           IsPtrMemT = CompoundT<T>::IsPtrMemT,           IsEnumT   = IsEnumT<T>::Yes,           IsClassT  = IsClassT<T>::Yes };};#endif // TYPET_HPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -