fork(2) download
  1. #include <iostream>
  2.  
  3. template <typename TagT, typename ClassT, typename MemberT>
  4. struct StaticPointerToMemberTraits
  5. {
  6. using ClassType = ClassT;
  7. using MemberType = MemberT;
  8. using PointerToMemberType = MemberType ClassType::*;
  9. static PointerToMemberType pointerToMember;
  10. };
  11. template <typename TagT, typename ClassT, typename MemberT>
  12. MemberT ClassT::* StaticPointerToMemberTraits<TagT, ClassT, MemberT>::pointerToMember = nullptr;
  13.  
  14. template <typename TagT> using ClassType = typename TagT::ClassType;
  15. template <typename TagT> using MemberType = typename TagT::MemberType;
  16. template <typename TagT> using PointerToMemberType = typename TagT::PointerToMemberType;
  17.  
  18. template <typename TagT, PointerToMemberType<TagT> pointerToMember>
  19. class PrivateMemberAccessEnabler
  20. {
  21. PrivateMemberAccessEnabler() { TagT::pointerToMember = pointerToMember; }
  22. static PrivateMemberAccessEnabler instance;
  23. };
  24. template <typename TagT, PointerToMemberType<TagT> pointerToMember>
  25. PrivateMemberAccessEnabler<TagT, pointerToMember>
  26. PrivateMemberAccessEnabler<TagT, pointerToMember>::instance;
  27.  
  28. template <typename TagT>
  29. class PrivateMemberAccessor
  30. {
  31. public:
  32. explicit PrivateMemberAccessor(ClassType<TagT>& obj) : m_obj(&obj) {}
  33.  
  34. MemberType<TagT>& operator* () const { return m_obj->*TagT::pointerToMember; }
  35. MemberType<TagT>* operator-> () const { return &m_obj->*TagT::pointerToMember; }
  36.  
  37. private:
  38. ClassType<TagT>* m_obj;
  39. };
  40.  
  41. #define ENABLE_PIVATE_MEMBER_ACCESS(TagT, ClassT, MemberT, member) \
  42.   struct TagT : StaticPointerToMemberTraits<TagT, ClassT, MemberT> { }; \
  43.   template class PrivateMemberAccessEnabler<TagT, &ClassT::member>;
  44.  
  45. class A
  46. {
  47. public:
  48.  
  49. explicit A(int value) : m_value(value) { }
  50.  
  51. int GetValue() const { return m_value; }
  52.  
  53. private:
  54. int m_value;
  55. };
  56.  
  57. ENABLE_PIVATE_MEMBER_ACCESS(A_value, A, int, m_value)
  58.  
  59. int main()
  60. {
  61. A a(1);
  62. std::cout << "a.GetValue(): " << a.GetValue() << std::endl;
  63. *PrivateMemberAccessor<A_value>(a) = 42;
  64. std::cout << "a.GetValue(): " << a.GetValue() << std::endl;
  65. }
  66.  
  67.  
Success #stdin #stdout 0s 15232KB
stdin
Standard input is empty
stdout
a.GetValue(): 1
a.GetValue(): 42