Удаление указателя класса из типа указателя на функцию-член - PullRequest
7 голосов
/ 21 июня 2019

Я видел этот фрагмент кода в примере cppreference для std :: is_function, и я не понимаю, как он работает.Может ли кто-нибудь объяснить мне, почему U выводится так же, как в PM_traits?

struct A {
  int fun() const&;
};

template<typename>
struct PM_traits {}; 

template<class T, class U>
struct PM_traits<U T::*> {
  using member_type = U;
};

int main() {
  using T = PM_traits<decltype(&A::fun)>::member_type; // T is int() const&
}

1 Ответ

11 голосов
/ 21 июня 2019

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::* вместо *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...