Search code examples
classtemplatesfriend

Accessing private member values with external template function


I'm a noob of c++, I'm trying to use a template function to get the private members inside a class because there are two types of parameters. What I wrote is like:

template <typename Type>
Type const& Get(Type const& value)
{
  return value;
}

class Event{
public:
Event(int const InputYear, int const InputMonth, int const InputDay, char const* InputContent, char const* InputNa    me = "None")
       :Year(InputYear), Month(InputMonth), Day(InputDay), Content(InputContent), Name(InputName)
  {
      
  }
   
  ~Event();
 
private:
  int Year;
  int Month;
  int Day;
  char* Content;
  char* Name;
 
  friend Type const& Get(Type const& value);
};

I don't know if my definition of friend is correct, if not could someone tell me how to use such template to access the private members?


Solution

  • The specification tells us that under certain circumstances (in this case explicit template instantiations), the usual access checking rules are not applied.

    12 The usual access checking rules do not apply to names used to specify explicit instantiations. [ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. — end note ]

    Thus, we can use this property to make a generic getter to a private member.

    template <auto Event::* Member>
    struct Getter {
        friend auto &get(Event &e) { return e.*Member; }
    };
    
    template struct Getter<&Event::Year>;
    auto &get(Event &e);
    
    Event event{2021, 12, 24, "some event description"};
    int year = get(event); // 2021