Skip to content

Instantly share code, notes, and snippets.

@douduck08
Last active February 12, 2025 08:27
Show Gist options
  • Save douduck08/0837272a8344785ed4afd4294f321882 to your computer and use it in GitHub Desktop.
Save douduck08/0837272a8344785ed4afd4294f321882 to your computer and use it in GitHub Desktop.
#include <iostream>
// Define the template function `GetMember`.
// This function will be the friend non-member function of the class `ClassType`.
template <typename ClassType, typename ClassType::MemberType member>
struct AccessPrivate
{
friend typename ClassType::MemberType GetMember(ClassType)
{
return member;
}
};
struct A
{
A() : x(100) {}
private:
int x;
};
// Declare a tag struct.
struct A_x_AccessTag
{
// typedef the `MemberType` for `GetMember(A_x_AccessTag)` function.
// In this case, `MemberType` will be a pointer that point to "an int member variable of class A".
typedef int A::*MemberType;
// Declare GetMember(A_x_AccessTag) as a friend function.
friend MemberType GetMember(A_x_AccessTag);
};
// Specialize the function `GetMember<A_x_AccessTag>` to access the member `A::x`.
// In this case, will declare a varable:
// A_x_AccessTag::MemberType member = &A::x;
// Is the same as:
// int A::*member = &A::x;
template struct AccessPrivate<A_x_AccessTag, &A::x>;
int main()
{
A a;
// GetMember(A_x_AccessTag()) will return the pointer to member `&A::x`.
// And use .* operator to access `A::x` of a.
std::cout << "Hello private memeber: " << a.*GetMember(A_x_AccessTag()) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment