What is the purpose of the following esoteric C++ operators?
Pointer to member
::*
Bind pointer to member by pointer
They relate to pointers-to-members and pointers-to-member-functions.
struct Foo {
int a() { return 1; }
int b() { return 2; }
int c;
};
int main() {
Foo f;
f.c = 3;
typedef int (Foo::*member_fn)(); // pointer-to-member-function
typedef int (Foo::*data_member); // pointer-to-member
member_fn mf = &Foo::a;
(f.*mf)(); // calls the member function pointed to by mf. returns 1
mf = &Foo::b;
(f.*mf)(); // This time, returns 2, since mf points to b
Foo *fp = &f;
(fp->*mf)(); // same thing, via pointer to f instead of object/reference f.
data_member dm = &Foo::c;
f.*dm; // is 3
f.*dm = 5;
f.c; // is now 5.
Foo f2; // another instance
f2.c = 12;
f2.*dm; // is 12. Same pointer-to-member, different object.
}
Although it might look like one, ::* isn't an operator. It's the :: operator and the * operator type modifier next to each other. To prove this without resorting to reading the standard, try adding spaces: :: * compiles, . * doesn't, neither does -> *.
As for what they're actually useful for - same principle as function pointers. You wouldn't use them as I have above, in a situation where you could just call the function by name, but you can pass them as parameters or return them from functions, store them, or select one of several based on complicated logic.
If it helps, I believe the syntax is chosen so that although .* is an indivisible single operator, you can imagine that *dm "means" c, the member pointed to by dm. So if dm points to c, then f.*dm is the same as f.c.