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;
}