Sapere il tipo di una variabile ha senso solo nel contesto dei template. Negli altri casi o la sai già (visto che da qualche parte l'hai dichiarata), oppure in C++11 lo ricavi con il type inference usando decltype su una variabile già definita. La tua funzione pertanto deve essere un template con all'interno i vari traits che intendi usare per identificare ciò che passi.
Ad esempio.
template <typename T>
struct which_type identify(T& var) {
which_type mtype;
memset(&type,0,sizeof(which_type));
m_type.is_int = std::is_integer<T>::value;
m_type.size = sizeof(T);
m_type.is_float_or_double = std::is_floating_point<T>::value;
// etc.
}
Vettori e matrici sono riconosciuti da questo modo di procedere solo se posti nello stack.
Questo per quel che riguarda il compile time.
Se hai bisogno di confronti runtime devi usare la RTTI del C++ che però non fornisce le informazioni che chiedi, ma permette di confrontare il tipo del dato passato a parametro con uno di riferimento.
Tornando all'esempio di prima:
template <typename T>
struct which_type identify(T& var) {
which_type mtype;
memset(&type,0,sizeof(which_type));
m_type.is_int = (typeid(var) == typeid(int));
m_type.size = sizeof(T);
m_type.is_float_or_double = (typeid(var) == typeid(float)) ||(typeid(var) == typeid(double)) ;
// etc.
}
Per curiosità: a che ti serve sapere il tipo?