Важно отметить, что decltype
имеет два значения: его можно использовать для поиска объявленного типа (отсюда и его имя) сущности , или его можно использовать для проверки выражение . Я здесь использую сущность свободно и не имею в виду какой-либо термин Стандарта, а, проще говоря, это может быть переменная, функция или (как ни странно, на мой взгляд) доступ к члену. Тип, возвращаемый при проверке выражения, чаще всего отличается от типа самого выражения, поэтому:
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( t.i ), 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( (t.i) ), int&>::value, "" );
Обратите внимание, как это работает для функций, и, следовательно, в вашем случае decltype(*&f)
совпадает с decltype( (f) )
, а не decltype(f)
.