It is important to note that decltype has two meanings: it can be used to search for the declared type (hence its name) of an object or it can be used to test an expression. I use the entity here freely and do not mean a single term of the Standard, but, simply put, it can be a variable, function or (oddly enough, in my opinion) membership access. The type returned by checking the expression most often differs from the type of the expression itself, thus:
int i; void foo(); struct { int i; } t; static_assert( std::is_same<decltype( i ), int>::value, "" ); static_assert( std::is_same<decltype( foo ), void()>::value, "" ); static_assert( std::is_same<decltype( ti ), int>::value, "" ); static_assert( std::is_same<decltype( (i) ), int&>::value, "" ); static_assert( std::is_same<decltype( (foo) ), void(&)()>::value, "" ); static_assert( std::is_same<decltype( (ti) ), int&>::value, "" );
Notice how this works for functions, and therefore in your case decltype(*&f) matches decltype( (f) ) , not decltype(f) .
source share