Ru-Brd |
Now that we are able to classify any type according to its kind, it is convenient to group all the classifying templates in a single general-purpose template. The following relatively small header file does just that: // types/typet.hpp #ifndef TYPET_HPP #define TYPET_HPP // define IsFundaT<> #include "type1.hpp" // define primary template CompoundT<> (first version) //#include "type2.hpp" // define primary template CompoundT<> (second version) #include "type6.hpp" // define CompoundT<> specializations #include "type3.hpp" #include "type4.hpp" #include "type5.hpp" // define IsEnumT<> #include "type7.hpp" // define IsClassT<> #include "type8.hpp" // define template that handles all in one style template <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 The following program shows an application of all these classification templates: // types/types.cpp #include "typet.hpp" #include <iostream> class MyClass { }; void myfunc() { } enum E { e1 }; // check by passing type as template argument template <typename T> void check() { if (TypeT<T>::IsFundaT) { std::cout << " IsFundaT "; } if (TypeT<T>::IsPtrT) { std::cout << " IsPtrT "; } if (TypeT<T>::IsRefT) { std::cout << " IsRefT "; } if (TypeT<T>::IsArrayT) { std::cout << " IsArrayT "; } if (TypeT<T>::IsFuncT) { std::cout << " IsFuncT "; } if (TypeT<T>::IsPtrMemT) { std::cout << " IsPtrMemT "; } if (TypeT<T>::IsEnumT) { std::cout << " IsEnumT "; } if (TypeT<T>::IsClassT) { std::cout << " IsClassT "; } std::cout << std::endl; } // check by passing type as function call argument template <typename T> void checkT (T) { check<T>(); // for pointer types check type of what they refer to if (TypeT<T>::IsPtrT TypeT<T>::IsPtrMemT) { check<typename CompoundT<T>::BaseT>(); } } int main() { std::cout << "int:" << std::endl; check<int>(); std::cout << "int&:" << std::endl; check<int&>(); std::cout << "char[42]:" << std::endl; check<char[42]>(); std::cout << "MyClass:" << std::endl; check<MyClass>(); std::cout << "ptr to enum:" << std::endl; E* ptr = 0; checkT(ptr); std::cout << "42:" << std::endl; checkT(42); std::cout << "myfunc():" << std::endl; checkT(myfunc); std::cout << "memptr to array:" << std::endl; char (MyClass::* memptr) [] = 0; checkT(memptr); } The program has the following output: int: IsFundaT int&: IsRefT char[42]: IsArrayT MyClass: IsClassT ptr to enum: IsPtrT IsEnumT 42: IsFundaT myfunc(): IsPtrT IsFuncT memptr to array: IsPtrMemT IsArrayT |
Ru-Brd |