In reference to May pointer to members circumvent the access level of a member?, I would like to understand the code snippet in that question.
I will paste the code snippet here.
#include <iostream>
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
Among a few questions, I highlight a single question here that may crack open the rest.
I do not understand the following statement in the main function:
a.*get(A_f())
I do understand (I think) that get(A_F()) returns a pointer to a.a. However, I do not understand the get() function. In what struct is this actually defined? How is it being accessed in that struct?
I have two secondary questions that may be answered if the above question is answered, but I will place them here. First, in the definition of Rob, the friend keyword is being used in front of the function get that is being defined, as well as declared. I thought that the friend keyword can only be used in front of a function declaration to indicate that a function defined elsewhere has access to the private/protected members of the class. Can someone explain?
Second, I do not understand the line template struct Rob<A_f, &A::a>;. I do not understand the use of the template keyword without <...>, and I do not understand why there is no template definition – this seems to be some sort of forward declaration. Can someone explain? Thanks.
First thing first: the function
get()is a friend of bothAandRobclass template. It is not a member function of any class. It is rather a free function.Now, where exactly is this free function defined? Well it is defined in
Robclass template, and at the same time it is declared asfriendofRobclass template.Yes it can be declared
friendof a class, without defining it inside the class. It can also be defined inside a class and at the same time can be declaredfriendof that class. In your case, it is actually defined in the class itself.That is called explicit instantiation of the class template with the given tempate arguments. You can see many other syntax to explicitly instantiate a template here (well if it is a function template):