fork download
  1. #include <iostream>
  2.  
  3. struct A
  4. {
  5. public:
  6.  
  7. int GetValue() const { return value; }
  8.  
  9. private:
  10. int q[100];
  11.  
  12. int value = -1;
  13. };
  14.  
  15. template<class MemberPtr, MemberPtr Mem>
  16. struct MemberTag;
  17.  
  18.  
  19. template<typename T>
  20. struct MemberOffset
  21. {
  22. static intptr_t offset;
  23. };
  24.  
  25. template<typename T>
  26. intptr_t MemberOffset<T>::offset;
  27.  
  28.  
  29. template<typename T>
  30. struct Registrator
  31. {
  32. template<class PointerToMemberType, PointerToMemberType Member>
  33. struct RegistratorInner
  34. {
  35. using TheType = PointerToMemberType;
  36. static constexpr TheType TheMember = Member;
  37.  
  38. struct OffsetInitializer
  39. {
  40. OffsetInitializer()
  41. {
  42. // Hack to get runtime value of pointer-to-member
  43. union PtrUnion
  44. {
  45. PointerToMemberType m;
  46. intptr_t i;
  47. };
  48.  
  49.  
  50. PtrUnion p;
  51. p.m = Member;
  52.  
  53. MemberOffset<T>::offset = p.i;
  54. }
  55. };
  56.  
  57. static OffsetInitializer offsetInitializer;
  58. };
  59. };
  60.  
  61.  
  62. template<typename T>
  63. template<class PointerToMemberType, PointerToMemberType Member>
  64. typename Registrator<T>::template RegistratorInner<PointerToMemberType, Member>::OffsetInitializer
  65. Registrator<T>::RegistratorInner<PointerToMemberType, Member>::offsetInitializer;
  66.  
  67.  
  68. template<class T>
  69. struct MemberExtractor {};
  70.  
  71. // Extractor specialization
  72. template<class PointerToMemberType, PointerToMemberType Member>
  73. struct MemberExtractor<MemberTag<PointerToMemberType, Member>>
  74. {
  75. using TheType = PointerToMemberType;
  76. static constexpr TheType TheMember = Member;
  77. };
  78.  
  79. // Private member specialization
  80. template<>
  81. struct MemberTag<decltype(&A::value), &A::value>
  82. {
  83. using TheType = typename MemberExtractor<MemberTag>::TheType;
  84. static constexpr TheType TheMember = MemberExtractor<MemberTag>::TheMember;
  85.  
  86. // Extract type
  87. virtual typename Registrator<A>::RegistratorInner<TheType, TheMember>::OffsetInitializer F()
  88. {
  89. return Registrator<A>::RegistratorInner<TheType, TheMember>::offsetInitializer;
  90. }
  91. };
  92.  
  93. template<>
  94. struct MemberTag<decltype(&A::value), &A::value>;
  95.  
  96. int main()
  97. {
  98. std::cout << MemberOffset<A>::offset; // 400
  99. }
  100.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:87:73: error: ‘MemberTag<int A::*, &A::value>::TheMember’ is not a valid template argument for type ‘int A::*’
     virtual typename Registrator<A>::RegistratorInner<TheType, TheMember>::OffsetInitializer F()
                                                                         ^
prog.cpp:87:73: error: it must be a pointer-to-member of the form ‘&X::Y’
prog.cpp:87:73: error: could not convert template argument ‘MemberTag<int A::*, &A::value>::TheMember’ to ‘int A::*’
prog.cpp: In member function ‘virtual int MemberTag<int A::*, &A::value>::F()’:
prog.cpp:89:67: error: ‘MemberTag<int A::*, &A::value>::TheMember’ is not a valid template argument for type ‘int A::*’
         return Registrator<A>::RegistratorInner<TheType, TheMember>::offsetInitializer;
                                                                   ^
prog.cpp:89:67: error: it must be a pointer-to-member of the form ‘&X::Y’
prog.cpp:89:67: error: could not convert template argument ‘MemberTag<int A::*, &A::value>::TheMember’ to ‘int A::*’
stdout
Standard output is empty