Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   pointer to a member of a member (http://www.velocityreviews.com/forums/t622604-pointer-to-a-member-of-a-member.html)

huili80@gmail.com 06-27-2008 04:47 PM

pointer to a member of a member
 
Say I have two classes:

class A
{
public:
int x;
};

class B
{
public:
A a;
};

Then how do I construct a member pointer to B::a.x ? What's the syntax
for it?
Thanks!

n2xssvv.g02gfr12930 06-27-2008 05:50 PM

Re: pointer to a member of a member
 
huili80@gmail.com wrote:
> Say I have two classes:
>
> class A
> {
> public:
> int x;
> };
>
> class B
> {
> public:
> A a;
> };
>
> Then how do I construct a member pointer to B::a.x ? What's the syntax
> for it?
> Thanks!


Not sure what you require, but the code sample below may be of help

int A::*ptr = A::x;
A Example;
Example.*ptr = 15;

JB

n2xssvv.g02gfr12930 06-27-2008 06:45 PM

Re: pointer to a member of a member
 
Victor Bazarov wrote:
> n2xssvv.g02gfr12930 wrote:
>> huili80@gmail.com wrote:
>>> Say I have two classes:
>>>
>>> class A
>>> {
>>> public:
>>> int x;
>>> };
>>>
>>> class B
>>> {
>>> public:
>>> A a;
>>> };
>>>
>>> Then how do I construct a member pointer to B::a.x ? What's the syntax
>>> for it?
>>> Thanks!

>>
>> Not sure what you require, but the code sample below may be of help
>>
>> int A::*ptr = A::x;

>
> int A::*ptr = &A::x;
>
> (without the ampersand it's not legal).
>
>> A Example;
>> Example.*ptr = 15;

>
> Now do that for a 'B'... :-)
>
> V


A careless mistake, cheers Victor

JB

Greg Herlihy 06-27-2008 06:48 PM

Re: pointer to a member of a member
 
On Jun 27, 10:42*am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> huil...@gmail.com wrote:
> > Say I have two classes:

>
> > class A
> > {
> > public:
> > * * int x;
> > };

>
> > class B
> > {
> > public:
> > * * A a;
> > };

>
> > Then how do I construct a member pointer to B::a.x ? What's the syntax
> > for it?

>
> Why do you think you need it? *Does this help:
>
> * * *B b;
> * * *int *ptr = &b.a.x;


The question seems to me to be asking for a member pointer - not a
pointer to a (data) member. If that is the case, then the answer would
be that it is not possible to create a single, member pointer to
b.a.x. Instead it is necessary to declare two member pointers (one for
B::a and the other for A::x) and then apply them both. For example:

struct A
{
int x;
};

struct B
{
A a;
};

int main()
{
B b;
A B::*pa = &B::a;
int A::*pi = &A::x;

b.*pa.*pi = 3; // assigns 3 to b.a.x
}

Greg


huili80@gmail.com 06-27-2008 07:33 PM

Re: pointer to a member of a member
 
On Jun 27, 3:00*pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Greg Herlihy wrote:
> > On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> >> huil...@gmail.com wrote:
> >>> Say I have two classes:
> >>> class A
> >>> {
> >>> public:
> >>> * * int x;
> >>> };
> >>> class B
> >>> {
> >>> public:
> >>> * * A a;
> >>> };
> >>> Then how do I construct a member pointer to B::a.x ? What's the syntax
> >>> for it?
> >> Why do you think you need it? *Does this help:

>
> >> * * *B b;
> >> * * *int *ptr = &b.a.x;

>
> > The question seems to me to be asking for a member pointer - not a
> > pointer to a (data) member. If that is the case, then the answer would
> > be that it is not possible to create a single, member pointer to
> > b.a.x. Instead it is necessary to declare two member pointers (one for
> > B::a and the other for A::x) and then apply them both. For example:

>
> > * * struct A
> > * * {
> > * * * * int x;
> > * * };

>
> > * * struct B
> > * * {
> > * * * * A a;
> > * * };

>
> > * * int main()
> > * * {
> > * * * * B * b;
> > * * * * A * B::*pa = &B::a;
> > * * * * int A::*pi = &A::x;

>
> > * * * * b.*pa.*pi = 3; // assigns 3 to b.a.x
> > * * }

>
> > Greg

>
> I would like to see what the OP has to say about his/her need to create
> such a construct.
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


Here is an example (probably over-simplified from the actual case I'm
working on). Say I have a 2D vector class:

struct vector2d
{
double x,y;
static double vector2d::* const _v[2];
double& operator[] (int i) { return this->*_v[i]; }
const double& operator[] (int i) const { return this->*_v[i]; }
};
double vector2d::* const vector2d::_v[] = { &vector2d::x,
&vector2d::y };

and suppose we have an object "vector2d v;" . The purpose of using
pointer to member here is to make v[0] and v.x have exactly the same
run-time efficiency, provided that the compiler is capable of
necessary optimization. (I didn't invent this technique, but I forgot
where I learned it).

Suppose now for some reason, I want to build a 5D vector class out of
this 2D vector class, say like this.

class vector5d
{
vector2d v1, v2;
double z;
};

and we have an object "vector5d w;"

What I want is, with as little run-time overhead as possible (maybe
using a similar method that's used by vector2d), that w[0] gives me
w.v1.x , w[1] gives w.v1.y , w[2] gives w.v2.x , w[3] gives w.v2.y ,
and w[4] gives me w.z .

Is it possible? If yes, how?

Thanks!

huili80@gmail.com 06-27-2008 07:45 PM

Re: pointer to a member of a member
 
On Jun 27, 3:33*pm, huil...@gmail.com wrote:
> On Jun 27, 3:00*pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>
>
>
> > Greg Herlihy wrote:
> > > On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> > >> huil...@gmail.com wrote:
> > >>> Say I have two classes:
> > >>> class A
> > >>> {
> > >>> public:
> > >>> * * int x;
> > >>> };
> > >>> class B
> > >>> {
> > >>> public:
> > >>> * * A a;
> > >>> };
> > >>> Then how do I construct a member pointer to B::a.x ? What's the syntax
> > >>> for it?
> > >> Why do you think you need it? *Does this help:

>
> > >> * * *B b;
> > >> * * *int *ptr = &b.a.x;

>
> > > The question seems to me to be asking for a member pointer - not a
> > > pointer to a (data) member. If that is the case, then the answer would
> > > be that it is not possible to create a single, member pointer to
> > > b.a.x. Instead it is necessary to declare two member pointers (one for
> > > B::a and the other for A::x) and then apply them both. For example:

>
> > > * * struct A
> > > * * {
> > > * * * * int x;
> > > * * };

>
> > > * * struct B
> > > * * {
> > > * * * * A a;
> > > * * };

>
> > > * * int main()
> > > * * {
> > > * * * * B * b;
> > > * * * * A * B::*pa = &B::a;
> > > * * * * int A::*pi = &A::x;

>
> > > * * * * b.*pa.*pi = 3; // assigns 3 to b.a.x
> > > * * }

>
> > > Greg

>
> > I would like to see what the OP has to say about his/her need to create
> > such a construct.

>
> > V
> > --
> > Please remove capital 'A's when replying by e-mail
> > I do not respond to top-posted replies, please don't ask

>
> Here is an example (probably over-simplified from the actual case I'm
> working on). Say I have a 2D vector class:
>
> struct vector2d
> {
> * * double x,y;
> * * static double vector2d::* const _v[2];
> * * double& operator[] (int i) { return this->*_v[i]; }
> * * const double& operator[] (int i) const { return this->*_v[i]; }};
>
> double vector2d::* const vector2d::_v[] = { &vector2d::x,
> &vector2d::y };
>
> and suppose we have an object "vector2d v;" . The purpose of using
> pointer to member here is to make v[0] and v.x have exactly the same
> run-time efficiency, provided that the compiler is capable of
> necessary optimization. (I didn't invent this technique, but I forgot
> where I learned it).
>
> Suppose now for some reason, I want to build a 5D vector class out of
> this 2D vector class, say like this.
>
> class vector5d
> {
> * * vector2d v1, v2;
> * * double z;
>
> };
>
> and we have an object "vector5d w;"
>
> What I want is, with as little run-time overhead as possible (maybe
> using a similar method that's used by vector2d), that w[0] gives me
> w.v1.x , w[1] gives w.v1.y , w[2] gives w.v2.x , w[3] gives w.v2.y ,
> and w[4] gives me w.z .
>
> Is it possible? If yes, how?

I mean, is it possible to achieve zero run-time overhead (assuming
proper optimization) in accessing members (and their members) via an
index? If we don't have a vector5d::z (in which case it's actually a
4D vector), we might want to use an array of pointers to member of a
member (I don't know how even if they do exist). Having vector5d::z
makes this even more complicated in that a pointer to vector5d::z and
a (may or may not existing) pointer to vector5d::v1.x certainly would
have different types, so they cannot be put into an array.
>
> Thanks!



huili80@gmail.com 06-27-2008 08:12 PM

Re: pointer to a member of a member
 
On Jun 27, 4:04*pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> huil...@gmail.com wrote:
> > On Jun 27, 3:33 pm, huil...@gmail.com wrote:
> >> On Jun 27, 3:00 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:

>
> >>> Greg Herlihy wrote:
> >>>> On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> >>>>> huil...@gmail.com wrote:
> >>>>>> Say I have two classes:
> >>>>>> class A
> >>>>>> {
> >>>>>> public:
> >>>>>> * * int x;
> >>>>>> };
> >>>>>> class B
> >>>>>> {
> >>>>>> public:
> >>>>>> * * A a;
> >>>>>> };
> >>>>>> Then how do I construct a member pointer to B::a.x ? What's the syntax
> >>>>>> for it?
> >>>>> Why do you think you need it? *Does this help:
> >>>>> * * *B b;
> >>>>> * * *int *ptr = &b.a.x;
> >>>> The question seems to me to be asking for a member pointer - not a
> >>>> pointer to a (data) member. If that is the case, then the answer would
> >>>> be that it is not possible to create a single, member pointer to
> >>>> b.a.x. Instead it is necessary to declare two member pointers (one for
> >>>> B::a and the other for A::x) and then apply them both. For example:
> >>>> * * struct A
> >>>> * * {
> >>>> * * * * int x;
> >>>> * * };
> >>>> * * struct B
> >>>> * * {
> >>>> * * * * A a;
> >>>> * * };
> >>>> * * int main()
> >>>> * * {
> >>>> * * * * B * b;
> >>>> * * * * A * B::*pa = &B::a;
> >>>> * * * * int A::*pi = &A::x;
> >>>> * * * * b.*pa.*pi = 3; // assigns 3 to b.a.x
> >>>> * * }
> >>>> Greg
> >>> I would like to see what the OP has to say about his/her need to create
> >>> such a construct.
> >>> V
> >>> --
> >>> Please remove capital 'A's when replying by e-mail
> >>> I do not respond to top-posted replies, please don't ask
> >> Here is an example (probably over-simplified from the actual case I'm
> >> working on). Say I have a 2D vector class:

>
> >> struct vector2d
> >> {
> >> * * double x,y;
> >> * * static double vector2d::* const _v[2];
> >> * * double& operator[] (int i) { return this->*_v[i]; }
> >> * * const double& operator[] (int i) const { return this->*_v[i]; }};

>
> >> double vector2d::* const vector2d::_v[] = { &vector2d::x,
> >> &vector2d::y };

>
> >> and suppose we have an object "vector2d v;" . The purpose of using
> >> pointer to member here is to make v[0] and v.x have exactly the same
> >> run-time efficiency, provided that the compiler is capable of
> >> necessary optimization. (I didn't invent this technique, but I forgot
> >> where I learned it).

>
> >> Suppose now for some reason, I want to build a 5D vector class out of
> >> this 2D vector class, say like this.

>
> >> class vector5d
> >> {
> >> * * vector2d v1, v2;
> >> * * double z;

>
> >> };

>
> >> and we have an object "vector5d w;"

>
> >> What I want is, with as little run-time overhead as possible (maybe
> >> using a similar method that's used by vector2d), that w[0] gives me
> >> w.v1.x , w[1] gives w.v1.y , w[2] gives w.v2.x , w[3] gives w.v2.y ,
> >> and w[4] gives me w.z .

>
> >> Is it possible? If yes, how?

> > I mean, is it possible to achieve zero run-time overhead (assuming
> > proper optimization) in accessing members (and their members) via an
> > index? *If we don't have a vector5d::z (in which case it's actually a
> > 4D vector), we might want to use an array of pointers to member of a
> > member (I don't know how even if they do exist). Having vector5d::z
> > makes this even more complicated in that a pointer to vector5d::z and
> > a (may or may not existing) pointer to vector5d::v1.x certainly would
> > have different types, so they cannot be put into an array.
> >> Thanks!

>
> What you seem to be looking for is
>
> * * *struct vector5d
> * * *{
> * * * * *vector2d v1, v2;
> * * * * *double z;
> * * * * *double& operator[](int i) {
> * * * * * * *switch (i) {
> * * * * * * * * *case 0: return v1[0];
> * * * * * * * * *case 1: return v1[1];
> * * * * * * * * *case 2: return v2[0];
> * * * * * * * * *case 3: return v2[1];
> * * * * * * * * *case 4: return z;
> * * * * * * * * *default: throw "bad index";
> * * * * * * *}
> * * * * *}
> * * *};
>
> Isn't it?
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask



That gives the correct result, but not the best performance. A more
efficient solution would be

switch(i/2)
{
case 0: return v1[i%2]; break;
case 1: return v2[i%2]; break;
case 2: return z; break;
default: throw "bad index";
}


because v1[k] (as implemented in my earlier post) is much faster than

if ( k == 0 )
return v1.x;
else
return v1.y;


But can we achieve even better efficiency? Directing the program to
different branch based on the even- or odd-ness of an integer would
almost certainly be slower than just shifting a pointer by that
integer. That's exactly how in the vector2d class, v[0] has the same
efficiency as v.x . (again assuming proper optimization).

Frank Birbacher 06-27-2008 10:32 PM

Re: pointer to a member of a member
 
Hi!

Apart from what Victor says:

huili80@gmail.com schrieb:
> That gives the correct result, but not the best performance. A more
> efficient solution would be
>
> switch(i/2)
> {
> case 0: return v1[i%2]; break;
> case 1: return v2[i%2]; break;
> case 2: return z; break;
> default: throw "bad index";
> }


This is probably slower due to extra calculations

> because v1[k] (as implemented in my earlier post) is much faster than
>
> if ( k == 0 )
> return v1.x;
> else
> return v1.y;


Are you aware of the fact that the "switch" statement is supposed to be
optimized by table lookup. That means it cannot be compare to a series
of if-else statements. The "switch" can have a performance of O(1).
Which is exactly the same as your array. And I guess the table-lookup
optimization for the "switch" statement is more likely implemented than
a combination of function inlining and constant array lookup.

This optimization is why a switch will only accept integral values.

Anyway, unless you have measured runtime performance of an array of
member pointers compared to a chained if-else compared to a switch,
there is no point in discussing which one could be faster. It just depends.

Frank

huili80@gmail.com 06-28-2008 12:07 AM

Re: pointer to a member of a member
 
On Jun 27, 6:32*pm, Frank Birbacher <bloodymir.c...@gmx.net> wrote:
> Hi!
>
> Apart from what Victor says:
>
> huil...@gmail.com schrieb:
>
> > That gives the correct result, but not the best performance. A more
> > efficient solution would be

>
> > switch(i/2)
> > {
> > * *case 0: return v1[i%2]; break;
> > * *case 1: return v2[i%2]; break;
> > * *case 2: return z; break;
> > * *default: throw "bad index";
> > }

>
> This is probably slower due to extra calculations
>
> > because *v1[k] (as implemented in my earlier post) is much faster than

>
> > if ( k == 0 )
> > * *return v1.x;
> > else
> > * *return v1.y;

>
> Are you aware of the fact that the "switch" statement is supposed to be
> optimized by table lookup. That means it cannot be compare to a series
> of if-else statements. The "switch" can have a performance of O(1).
> Which is exactly the same as your array. And I guess the table-lookup
> optimization for the "switch" statement is more likely implemented than
> a combination of function inlining and constant array lookup.
>
> This optimization is why a switch will only accept integral values.
>
> Anyway, unless you have measured runtime performance of an array of
> member pointers compared to a chained if-else compared to a switch,
> there is no point in discussing which one could be faster. It just depends.
>
> Frank


I agree, without measurement it's meaningless to talk about
performance. But I wasn't asking about the performance in the first
place anyway (it appeared in a later example that was aksed for). Even
if the example was completely meansingless performance-wise, it
doesn't mean my question about "pointer to a member of a member" is
necessary meaningless.

I was trying to get an answer on how to get a "pointer to a member of
a member" if there exists something like that.
Maybe such a thing can be used in a good way, who knows.

Andrey Tarasevich 06-28-2008 01:09 AM

Re: pointer to a member of a member
 
huili80@gmail.com wrote:
>
> I was trying to get an answer on how to get a "pointer to a member of
> a member" if there exists something like that.
> Maybe such a thing can be used in a good way, who knows.


Of course, it can be. There's no real technical or conceptual difference
between 'pointer-to-data-member' and
'pointer-to-data-member-of-data-member'. They would be used in exactly
the same way.

Technically, the implementation of such a pointer would be exactly the
same as that of the existing 'pointer-to-data-member', meaning that the
pointer _type_ itself is already in the language. The only thing that's
really missing is the syntax that would let us to assign the proper
value to such a pointer.

Because of that latter part, the answer is no, you can't use such a
pointer in standard C++.

--
Best regards,
Andrey Tarasevich


All times are GMT. The time now is 10:41 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.