Ru-Brd |
To start, let's develop a template to determine whether a type is a fundamental type. By default, we assume a type is not fundamental, and we specialize the template for the fundamental cases: // types/type1.hpp // primary template: in general T is no fundamental type template <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_EXISTS MK_FUNDA_TYPE(float) MK_FUNDA_TYPE(double) MK_FUNDA_TYPE(long double) #undef MK_FUNDA_TYPE The primary template defines the general case. That is, in general, IsFundaT< T >::Yes will yield (or false ): template <typename T> class IsFundaT { public: enum{ Yes = 0, No = 1 }; }; For each fundamental type a specialization is defined so that IsFundaT< T >::Yes will yield 1 (or true ). This is done by defining a macro that expands the necessary code. For example, MK_FUNDA_TYPE(bool) expands to the following: template<> class IsFundaT<bool> { public: enum{ Yes = 1, No = 0 }; }; The following program demonstrates a possible use of this template: // types/type1test.cpp #include <iostream> #include "type1.hpp" template <typename T> void test (T const& t) { if (IsFundaT<T>::Yes) { std::cout << "T is fundamental type" << std::endl; } else { std::cout << "T is no fundamental type" << std::endl; } } class MyType { }; int main() { test(7); test(MyType()); } It has the following output: T is fundamental type T is no fundamental type In the same way, we can define type functions IsIntegralT and IsFloatingT to identify which of these types are integral scalar types and which are floating-point scalar types. |
Ru-Brd |