A cool thing with C++ is that it lets you create variables of pointer-to-member types. The most common use case seems to be to get a pointer to a method:
struct foo
{
int x() { return 5; }
};
int (foo::*ptr)() = &foo::x;
foo myFoo;
cout << (myFoo.*ptr)() << '\n'; // prints "5"
However, messing around, I realized that they can just as well point to member variables:
struct foo
{
int y;
};
int foo::*ptr = &foo::y;
foo myFoo;
myFoo.*ptr = 5;
cout << myFoo.y << '\n'; // prints "5"
This is pretty rad. It led me to a further experiment: what if you could get a pointer to a sub-member of a structure?
struct foo
{
int y;
};
struct bar
{
foo aFoo;
};
int bar::*foo::*ptr;
This actually compiles.
However, I have no idea how to assign it anything useful. None of the following works:
int bar::*foo::*ptr = &bar::foo::y; // no member named "foo" in "bar"
int bar::*foo::*ptr = &bar::aFoo::y; // no member named "aFoo" in "bar" (??)
int bar::*foo::*ptr = &foo::y; // can't init 'int bar::*foo::*' with 'int foo::*'
Furthermore, according to the error that this generates, it appears that this type is not exactly what I have in mind:
int bar::*foo::*ptr = nullptr;
bar myBar;
myBar.*ptr = 4; // pointer to member type ‘int bar::*’ incompatible
// with object type ‘bar’
It appears that this concept evades me. Obviously, I can't rule out that it simply gets parsed in a way entirely different from what I would expect.
Would anyone please explain me what an int bar::*foo::*
actually is? Why does gcc tell me that a pointer to a member of bar
is incompatible with a bar
object? How would I use an int bar::*foo::*
, and how would I construct a valid one?