![]() |
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! |
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 |
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 |
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 |
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! |
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! |
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). |
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 |
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. |
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 02:00 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.