Template types in std is_member_function_pointer

I mean a possible implementation std::is_member_function_pointer

here .

template< class T >
struct is_member_function_pointer_helper : std::false_type {};

template< class T, class U>
struct is_member_function_pointer_helper<T U::*> : std::is_function<T> {};

template< class T >
struct is_member_function_pointer : is_member_function_pointer_helper< std::remove_cv_t<T> >     


#include <type_traits>

class A {
public:
    void member() { }
};



int main()
{
    // fails at compile time if A::member is a data member and not a function
    static_assert(std::is_member_function_pointer<decltype(&A::member)>::value,
                  "A::member is not a member function."); 
}

      

I know that

"dectype (& A :: member)"

will be

"void (A :: *) ()"

But I don't understand what type T and type U are "void (A :: *) ()"?

+3


source to share


3 answers


The sample is void (A::*)()

decomposed into T U::*

, where U

- A

, and T

- void ()

. You can see the construction in reverse order, for example:

struct A {};

using T = void ();
using U = A;

template <typename> struct print;

int main() {
    print<T U::*>{};
    // error: implicit instantiation of undefined template 'print<void (A::*)()>'
}

      



So, T

as void ()

is passed to std::is_function

, which determines if the given type is a function.

In the case of a pointer to data members, this is not done, because the output T

will be non-functional.

+6


source


template< class T, class U>
struct is_member_function_pointer_helper<T U::*> : std::is_function<T> {};

      

The above specialization would be appropriate if it were possible to decompose the primary templated argument into a class U

type and a non-static member type T

. The class type is U

no longer useful here because we validated it is indeed a class.

The non-static type member T

is then passed as a template argument std::is_function

, which has many mechanisms in determining what is T

really a function.




But I don’t understand what type T

and type U

on the card in void (A::*)()

?

As explained above, once we can factorize void (A::*)()

into matches T U::*

, you will find what A::*

maps to U::*

. Let's delete this template, we are left with void ()

, which will be T

.

+4


source


It seems to me that it is easier to understand if we first translate the type identifier into English. That is, it is void (A::*)()

converted to "a pointer to a member of A

the type of () function that returns void

" and T U::*

to "a pointer to a member of the U

type class T

". Now, if we compare the two types, we can see what U

corresponds to the class A

, and what corresponds T

to the "return function ( void

"), i.e. void()

...

+2


source







All Articles