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