decltype deduces the type of expression, unless it is applied to a variable, in which case it deduces the type of that variable:
The type denoted by decltype(e) is defined as follows:
— if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
— otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
— otherwise, decltype(e) is the type of e.
§7.1.6.2 [dcl.type.simple]
Dereferencing a pointer yields an lvalue, and therefore decltype will deduce an lvalue reference to the type of the pointee:
The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.
§5.3.1 [expr.unary.op]
Therefore decltype(*p), for some pointer p, deduces an lvalue reference to the type of the pointee.
If you wish to get the type of the pointee from some pointer p, you can use:
std::remove_pointer<decltype(p)>::type
Or:
std::remove_reference<decltype(*p)>::type
Or, in your example, you can simply say foo, type deduction is not required.