Member pointer to array element

The problem is that, accessing an item in an array is another level of indirection from accessing a plain int. If that array was a pointer instead you wouldn't expect to be able to access the int through a member pointer.

struct foo
{
  int a;
  int *b;
};

int main()
{

  foo bar;
  int foo::* aptr=&(*foo::b); // You can't do this either!
  bar.a=1;
  std::cout << bar.*aptr << std::endl;
}

What you can do is define member functions that return the int you want:

struct foo
{
  int a;
  int *b;
  int c[2];

  int &GetA() { return a; } // changed to return references so you can modify the values
  int &Getb() { return *b; }
  template <int index>
  int &GetC() { return c[index]; }
};
typedef long &(Test::*IntAccessor)();

void SetValue(foo &f, IntAccessor ptr, int newValue)
{  
    cout << "Value before: " << f.*ptr();
    f.*ptr() = newValue;
    cout << "Value after: " << f.*ptr();
}

int main()
{
  IntAccessor aptr=&foo::GetA;
  IntAccessor bptr=&foo::GetB;
  IntAccessor cptr=&foo::GetC<1>;

  int local;
  foo bar;
  bar.a=1;
  bar.b = &local;
  bar.c[1] = 2;

  SetValue(bar, aptr, 2);
  SetValue(bar, bptr, 3);
  SetValue(bar, cptr, 4);
  SetValue(bar, &foo::GetC<0>, 5);
}

Then you at least have a consistent interface to allow you to change different values for foo.


However, the compiler just complains about an "invalid use of non-static data member 'foo::b'"

This is because foo::a and foo::b have different types. More specifically, foo::b is an array of size 2 of ints. Your pointer declaration has to be compatible i.e:

int (foo::*aptr)[2]=&foo::b;

Is it possible to do this at all (or at least without unions)?

Yes, see below:

struct foo
{
  int a;
  int b[2];
};

int main()
{

  foo bar;

  int (foo::*aptr)[2]=&foo::b;
  /* this is a plain int pointer */
  int *bptr=&((bar.*aptr)[1]);

  bar.a=1; 
  bar.b[0] = 2;
  bar.b[1] = 11;

  std::cout << (bar.*aptr)[1] << std::endl;
  std::cout << *bptr << std::endl;
}

Updated post with OP's requirements.