template<typename T> void tst(T) { using namespace std; // Strip away any references and pointer typedef remove_const<remove_pointer<decay<T>::type>::type>::type D; if(is_same<D, foo>::value) { cout << "same type" << endl; } else if(is_base_of<foo, D>::value) { cout << "extends type" << endl; } else { cout << "not related" << endl; } }