Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing class pointer from member function pointer type

I saw this code snippet in the example on cppreference for std::is_function and I don't understand how it works. Could someone explain to me why U gets deduced as it does in 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&
}
like image 340
willtunnels Avatar asked Jun 21 '19 19:06

willtunnels


1 Answers

U T::* is a type such that when we have U T::* p, p points to a member of class T, and that member is of type U.

fun is a function of type int () const &: a const &-qualified function taking no parameters and returning int, and it's a member of class A. Therefore, in the deduction, T is deduced to A and U is deduced to the type of A::fun, which is int () const &.


It may look a bit confusing, because if the type of &A::fun was spelled out explicitly, it would have to be written int (A::*)() const &. However, in the template's case, the type int () const & is "hidden" behind the name U, so the pointer to member is then just U A::*. It's similar to how type names can be used to simplify the syntax of normal function pointers:

int foo(char, double) { return 42; }

using Fun = int (char, double);
Fun *p = &foo;
// instead of:
int (*q)(char, double) = &foo;

The same happens in the template, just with A::* instead of *.

like image 136
Angew is no longer proud of SO Avatar answered Sep 23 '22 09:09

Angew is no longer proud of SO