I need to pass a pointer to data member, its type and the class it's a member of, to a template struct. The following works:
template<typename T, typename Cls, T Cls::*member> struct Member {};
struct Struct { int x; };
Member<int, Struct, &Struct::x>
But it requires to explicitly mention the type (T: int) and the class (Cls: Struct). That should be unnecessary. The compiler should be able to figure those two types out on its own.
In fact it can inferm them if I pass the pointer to data member to a function:
template<typename T, typename Cls> void member( T Cls::*member ) {}
struct Struct { int x; };
member( &Struct::x );
Is it possible to pass a pointer to data member as a non-type template argument, while letting the compiler figure out the type and class?
You can use a helper to get the type of the class and the member from the type of a member pointer:
template <typename T> struct type_from_member;
template <typename Cls,typename M>
struct type_from_member<M Cls::*> {
using class_type = Cls;
using member_type = M;
};
Then you can use auto
and inherit from the helper:
template <auto member> struct Mem : type_from_member<decltype(member)> {};
using B = Mem<&Struct::x>;
static_assert( std::is_same_v<B::member_type,int>);
static_assert( std::is_same_v<B::class_type,Struct>);