Listing 1: Portable typeof operator and test program
//================== The "typeof" machinery ================== // no definition, only specializations template<int N> struct select_type; template<class T> struct WrapType { typedef T WT; }; #define REGISTER_TYPEOF(N,T) \ template<> struct select_type<N> { \ typedef WrapType<T>::WT Type; }; \ char (*select_array(const WrapType<T>::WT &))[N]; #define typeof(x) select_type<sizeof(*select_array(x))>::Type //====== Registration of types to be used with "typeof" ====== REGISTER_TYPEOF( 1, char ) REGISTER_TYPEOF( 2, signed char ) REGISTER_TYPEOF( 3, unsigned char ) REGISTER_TYPEOF( 4, short ) REGISTER_TYPEOF( 5, unsigned short ) REGISTER_TYPEOF( 6, int ) REGISTER_TYPEOF( 7, unsigned int ) REGISTER_TYPEOF( 8, long ) REGISTER_TYPEOF( 9, unsigned long ) REGISTER_TYPEOF( 10, long long ) REGISTER_TYPEOF( 11, unsigned long long ) REGISTER_TYPEOF( 12, float ) REGISTER_TYPEOF( 13, double ) REGISTER_TYPEOF( 14, wchar_t ) REGISTER_TYPEOF( 15, int (*)() ) //======================= Test program ======================= #include <iostream.h> #include <typeinfo.h> int main() { short a; long b; typeof(a) c; typeof(b) d; typeof(1.0) e; typeof(main) f; cout << "c is " << typeid(c).name() << '\n'; cout << "d is " << typeid(d).name() << '\n'; cout << "e is " << typeid(e).name() << '\n'; cout << "f is " << typeid(f).name() << '\n'; return 0; }