U T::*
- это такой тип, что когда у нас есть U T::* p
, p
указывает на члена класса T
, а этот член имеет тип U
.
fun
является функцией типа int () const &
: const &
-качественная функция, не принимающая параметров и возвращающая int
, и она является членом класса A
. Следовательно, при выводе T
выводится на A
, а U
выводится на тип A::fun
, который равен int () const &
.
Это может показаться немного запутанным, потому что, если тип &A::fun
был прописан явно, он должен был бы быть написан int (A::*)() const &
. Однако в случае с шаблоном тип int () const &
скрыт за именем U
, поэтому указатель на член будет просто U A::*
. Это похоже на то, как имена типов могут использоваться для упрощения синтаксиса обычных указателей функций:
int foo(char, double) { return 42; }
using Fun = int (char, double);
Fun *p = &foo;
// instead of:
int (*q)(char, double) = &foo;
То же самое происходит в шаблоне, только с A::*
вместо *
.