#include <iostream>
struct A
{
public:
int GetValue() const { return value; }
private:
int q[100];
int value = -1;
};
template<class MemberPtr, MemberPtr Mem>
struct MemberTag;
template<typename T>
struct MemberOffset
{
static intptr_t offset;
};
template<typename T>
intptr_t MemberOffset<T>::offset;
template<typename T>
struct Registrator
{
template<class PointerToMemberType, PointerToMemberType Member>
struct RegistratorInner
{
using TheType = PointerToMemberType;
static constexpr TheType TheMember = Member;
struct OffsetInitializer
{
OffsetInitializer()
{
// Hack to get runtime value of pointer-to-member
union PtrUnion
{
PointerToMemberType m;
intptr_t i;
};
PtrUnion p;
p.m = Member;
MemberOffset<T>::offset = p.i;
}
};
static OffsetInitializer offsetInitializer;
};
};
template<typename T>
template<class PointerToMemberType, PointerToMemberType Member>
typename Registrator<T>::template RegistratorInner<PointerToMemberType, Member>::OffsetInitializer
Registrator<T>::RegistratorInner<PointerToMemberType, Member>::offsetInitializer;
template<class T>
struct MemberExtractor {};
// Extractor specialization
template<class PointerToMemberType, PointerToMemberType Member>
struct MemberExtractor<MemberTag<PointerToMemberType, Member>>
{
using TheType = PointerToMemberType;
static constexpr TheType TheMember = Member;
};
// Private member specialization
template<>
struct MemberTag<decltype(&A::value), &A::value>
{
using TheType = typename MemberExtractor<MemberTag>::TheType;
static constexpr TheType TheMember = MemberExtractor<MemberTag>::TheMember;
// Extract type
virtual typename Registrator<A>::RegistratorInner<TheType, TheMember>::OffsetInitializer F()
{
return Registrator<A>::RegistratorInner<TheType, TheMember>::offsetInitializer;
}
};
template<>
struct MemberTag<decltype(&A::value), &A::value>;
int main()
{
std::cout << MemberOffset<A>::offset; // 400
}