Pointer to class member array ... element? Possible?

K

Kaz Kylheku

Given some class C with array T x[N], is it possible to get a
pointer-to-data-member to one of the elements?

&C::x gives us a pointer-to-member-array: T (C::*)[N].

But I just want to get a T C::* pointing to a selected array element,
so that I can later use an instance c of that class to pick out that
array element: c->*ptr.

This syntax, for instance, doesn't work: &C::x[1]. My compiler thinks
I'm trying to do scope resolution to look up x as a member of some base
class: it complains that C isn't a base class of the class that I'm
working in. Of course &C::x works fine. How to sneak in that array
reference? (&C::x)[1] isn't it because then you are doing array
indexing on a pointer to the array, which is invalid; you need an
object to do that.

Is there any way? All I have is this hack:

T (C::*pma)[N] = &C::x; // pointer to member array

T C::*pe1 = (T C::*) ((size_t) pma + sizeof T);

The assumption is that the pointer-to-member is an integer-like offset
that can be converted to a size_t, subject to displacement by a
multiple of the array size and the converted back to pointer-to-member.
 
M

mlimber

Kaz said:
Given some class C with array T x[N], is it possible to get a
pointer-to-data-member to one of the elements?

&C::x gives us a pointer-to-member-array: T (C::*)[N].

But I just want to get a T C::* pointing to a selected array element,
so that I can later use an instance c of that class to pick out that
array element: c->*ptr.

This syntax, for instance, doesn't work: &C::x[1]. My compiler thinks
I'm trying to do scope resolution to look up x as a member of some base
class: it complains that C isn't a base class of the class that I'm
working in. Of course &C::x works fine. How to sneak in that array
reference? (&C::x)[1] isn't it because then you are doing array
indexing on a pointer to the array, which is invalid; you need an
object to do that.

Is there any way? All I have is this hack:

T (C::*pma)[N] = &C::x; // pointer to member array

T C::*pe1 = (T C::*) ((size_t) pma + sizeof T);

The assumption is that the pointer-to-member is an integer-like offset
that can be converted to a size_t, subject to displacement by a
multiple of the array size and the converted back to pointer-to-member.

Please post a minimal but complete sample program.

Cheers! --M
 
V

Victor Bazarov

Kaz said:
Given some class C with array T x[N], is it possible to get a
pointer-to-data-member to one of the elements?

IIUIC, an element of the member array is not a member of that class, so,
no, it should not be possible.
&C::x gives us a pointer-to-member-array: T (C::*)[N].
Right.

But I just want to get a T C::* pointing to a selected array element,
so that I can later use an instance c of that class to pick out that
array element: c->*ptr.

Keep the index instead. Can't you just do c->x[indexyoukeep] ?
This syntax, for instance, doesn't work: &C::x[1]. My compiler thinks
I'm trying to do scope resolution to look up x as a member of some base
class: it complains that C isn't a base class of the class that I'm
working in. Of course &C::x works fine. How to sneak in that array
reference? (&C::x)[1] isn't it because then you are doing array
indexing on a pointer to the array, which is invalid; you need an
object to do that.

Is there any way? All I have is this hack:

T (C::*pma)[N] = &C::x; // pointer to member array

T C::*pe1 = (T C::*) ((size_t) pma + sizeof T);

The assumption is that the pointer-to-member is an integer-like offset
that can be converted to a size_t, subject to displacement by a
multiple of the array size and the converted back to pointer-to-member.

Bad assumption. Imagine what's going to happen when you have multiple
(or, which is worse, virtual) inheritance... Well, I don't actually know
if it's bad, but I just shy away from things like that.

V
 
B

Branimir Maksimovic

Kaz Kylheku said:
T (C::*pma)[N] = &C::x; // pointer to member array

T C::*pe1 = (T C::*) ((size_t) pma + sizeof T);

The assumption is that the pointer-to-member is an integer-like offset
that can be converted to a size_t, subject to displacement by a
multiple of the array size and the converted back to pointer-to-member.

Try for example:
struct T{
char a[16];
};
int main()
{
char (T::*p)[16] = &T::a;
size_t p1 = *(size_t*)&p;
if(p) cout << sizeof(p)<<' '<<p1<<'\n';
}

p should return true but p1 could display 0.
If you write p = 0 explicitely then "if" wouldn't print.
It's more than a size_t.

Greetings, Bane.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,162
Latest member
GertrudeMa
Top