Yes, this code is valid, and the source of your confusion isn't actually related to templates.
int X::*
is a pointer-to-member (specifically a pointer to int
data member on type X
). The pointer itself does not convey an instance of the object, so you can indeed take a pointer to a non-static member. (In fact, a pointer to a static member would just be a regular pointer, not a pointer-to-member!)
You supply the object instance at the time you use the pointer, not at the time you take the pointer.
// Declare a pointer to a data member of type int on object of type X, and
// initialize it to point to the X::n member.
int X::*ptr = &X::n;
// *ptr is not valid on member pointers. Rather, we need to supply an instance:
X instance;
// Then use the member pointer dereference operator .*
(instance.*ptr) = 5; // Same as "instance.n = 5;" in this case.