By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,851 Members | 1,131 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,851 IT Pros & Developers. It's quick & easy.

pointer to a member of a member

P: n/a
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!
Jun 27 '08 #1
Share this Question
Share on Google+
31 Replies


P: n/a
hu*****@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;

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

P: n/a
hu*****@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
Jun 27 '08 #3

P: n/a
n2xssvv.g02gfr12930 wrote:
hu*****@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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #4

P: n/a
Victor Bazarov wrote:
n2xssvv.g02gfr12930 wrote:
>hu*****@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
Jun 27 '08 #5

P: n/a
On Jun 27, 10:42*am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
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

Jun 27 '08 #6

P: n/a
Greg Herlihy wrote:
On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>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
Jun 27 '08 #7

P: n/a
On Jun 27, 3:00*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Greg Herlihy wrote:
On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
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!
Jun 27 '08 #8

P: n/a
On Jun 27, 3:33*pm, huil...@gmail.com wrote:
On Jun 27, 3:00*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Greg Herlihy wrote:
On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>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!
Jun 27 '08 #9

P: n/a
hu*****@gmail.com wrote:
On Jun 27, 3:33 pm, huil...@gmail.com wrote:
>On Jun 27, 3:00 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>>Greg Herlihy wrote:
On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
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
Jun 27 '08 #10

P: n/a
On Jun 27, 4:04*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
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.netwrote:
>Greg Herlihy wrote:
On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
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).
Jun 27 '08 #11

P: n/a
hu*****@gmail.com wrote:
On Jun 27, 4:04 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>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.netwrote:
Greg Herlihy wrote:
>On Jun 27, 10:42 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>>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).
Are you sure about this? Has this been measured or is that your
theoretical conclusion? And if it has been measured, how much
difference on the application scale are we talking about?

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

P: n/a
Hi!

Apart from what Victor says:

hu*****@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
Jun 27 '08 #13

P: n/a
On Jun 27, 6:32*pm, Frank Birbacher <bloodymir.c...@gmx.netwrote:
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.
Jun 28 '08 #14

P: n/a
hu*****@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
Jun 28 '08 #15

P: n/a
On Jun 27, 9:09*pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
huil...@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
So since the pointer type is already in the language, but we just
can't assign a value to it, how can i explicitly get the type of the
pointer? (I just can't figure it out how...) Say what should we use to
replace the ... in the following so that ptr_type is a pointer to
B::a.x ?

class A { public: int x; };
class B { public: A a; };

typedef ... ptr_type;

Jun 28 '08 #16

P: n/a
On Jun 27, 12:45*pm, huil...@gmail.com wrote:
>
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.
If you really want to go ahead with a scheme to access class members
via an index, then I would suggest an implementation that takes the
opposite tack: that is, instead of accessing data members as if they
were elements of an array - access the elements of an array as if they
were individual data members.

Specifically, the vector classes could declare an array of doubles as
a member - and then declare various accessor methods that would return
the appropriate element from this array as the value of the
corresponding "virtual" data member. For example

class Vector2D
{
public:
Vector2D( x = 0.0, y = 0.0)
{
d_[0] = x;
d_[1] = y;
}

// operator[n] just returns d_[n]

double& operator[](int n)
{
assert(n >= and n <= sizeof(d_)/sizeof(d_[0]));

return d_[n];
}

// various methods for the "virtual" data members

double& x() { return d_[0]; }
const double& x() const { return d_[0]; }

double& x() { return d_[1]; }
const double& x() const { return d_[1]; }

private:
double d_[2];
};

class Vector3D
{
public:
Vector3D() : d_() {}

double& operator[](int n)
{
assert(n >= and n <= sizeof(d_)/sizeof(d_[0]));

return d_[n];
}

// Vector3D returns the v1 Vector2d "member" only on demand..

Vector2D v1() const { return Vector2D( d_[0], d_[1]); }

double v1_x() { return Vector2D( d_[0]; }
double v1_y() { return Vector2D( d_[1]); }

// declare v2 accessors here

double& z() { return d_[4]; }

private:
double[5] d_;
};

Greg

Jun 28 '08 #17

P: n/a
hu*****@gmail.com wrote:
On Jun 27, 9:09 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
>...
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.
...
So since the pointer type is already in the language, but we just
can't assign a value to it, how can i explicitly get the type of the
pointer? (I just can't figure it out how...) Say what should we use to
replace the ... in the following so that ptr_type is a pointer to
B::a.x ?

class A { public: int x; };
class B { public: A a; };

typedef ... ptr_type;
That would be

typedef int B::*ptr_type;

This might look surprising at first, but the truth is that technically a
pointer of type 'int B::*' is capable of pointing not only to direct
data members of 'B', but also to its indirect data members (in the above
sense of the word). The only problem is that there's no syntax in C++
that would allow us to make it point to 'B::a.x'. The natural syntax
would be something like

ptr_type p = &B::a.x;

but apparently the authors of the language never thought about it.

--
Best regards,
Andrey Tarasevich
Jun 28 '08 #18

P: n/a
On Jun 28, 12:32 am, Frank Birbacher <bloodymir.c...@gmx.netwrote:

[...]
Are you aware of the fact that the "switch" statement is
supposed to be optimized by table lookup.
Not really. The switch statement (like everything else in the
basic languaage) is supposed to be optimized in the most
effective way possible on the given platform. For many
platforms, this does mean a table of pointers to code if the
switch is "dense". There are machines, however, on which an
indirect jump is exceedingly expensive, and the sequence of if's
is actually faster, even for dense tables. (Remember, the
compiler will know all of the values, and will generated a
binary search with the if's, so you have at most O(ln n)
comparisons.)

The real point is that the compiler knows the architecture for
which it is generating code, and will use whatever technique is
optimal for that architecture. Trying to second guess it can
never improve performance.

[...]
This optimization is why a switch will only accept integral values.
Integral *constant* values.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 28 '08 #19

P: n/a
On Jun 27, 7:47 pm, 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?
Thanks!
Here is my solution to your problem :

I declare a data member in the B class : the void pointer p,
and I initialize it with the help of the constructor of the B
class.

Hope you are happy with this solution.

-------------------------------------------------------------
class A
{
public:
int x;
};

class B
{
public:
A a;
void *p;
B()
{
B::p = &(B::a.x);
};
};

int main()
{

return 0;
}
Jun 28 '08 #20

P: n/a
On Jun 28, 8:07*am, alexandrug <webaig...@gmail.comwrote:
On Jun 27, 7:47 pm, 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?
Thanks!

Here is my solution to your problem :

I declare a data member in the B class : the void pointer p,
and I initialize it with the help of the constructor of the B
class.

Hope you are happy with this solution.

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

class B
* * {
* * public:
* * * * A a;
* * * * void *p;
* * * * B()
* * * * {
* * * * B::p = &(B::a.x);
* * * * };
* * };

int main()
* * {

* * return 0;
* * }
I'm very happy with the solution. Thank you!
But what if I don't want to increase the size of B?
Jun 28 '08 #21

P: n/a
On Jun 28, 4:45 pm, huil...@gmail.com wrote:
On Jun 28, 8:07 am, alexandrug <webaig...@gmail.comwrote:
On Jun 27, 7:47 pm, 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?
Thanks!
Here is my solution to your problem :
I declare a data member in the B class : the void pointer p,
and I initialize it with the help of the constructor of the B
class.
Hope you are happy with this solution.
-------------------------------------------------------------
class A
{
public:
int x;
};
class B
{
public:
A a;
void *p;
B()
{
B::p = &(B::a.x);
};
};
int main()
{
return 0;
}

I'm very happy with the solution. Thank you!
But what if I don't want to increase the size of B?
Then the pointer would not be a member of the class B.
Jun 28 '08 #22

P: n/a
alexandrug wrote:
>I'm very happy with the solution. Thank you!
But what if I don't want to increase the size of B?

Then the pointer would not be a member of the class B.
Not a member? How?

Let me illustrate a couple of things by an example. The purpose of
pointer-to-member types is to facilitate nameless selection of class
members (as opposed to named selection we usually use).

For example, consider this code sample

struct A { int a; }

struct B {
int x;
int y;
A a;
int z[10];
};

void zero(B* b, unsigned n, int B::*m) {
for (; n 0; --n, ++b)
b->*m = 0;
}

Now, I can use the above simple 'zero' function I can set to zero any
immediate member of all 'B' objects in an array

B b[10];

zero(b, 10, &B::x); // sets all 'B::x's to zero
zero(b, 10, &B::y); // sets all 'B::y's to zero

Or I can choose what to zero based on some run-time criteria

zero(b, 10, rand() % 2 == 0 ? &B::x : &B::y);

This is the valuable run-time flexibility provided by pointers of
pointer-to-member type (in this case applied specifically to data members).

However, what if I want to zero 'B::a.x' members in the 'b' array? Or
what about zeroing 'B::z[5]' in each element of the 'b' array? In C++
you can't do that. And the truth is that from the implementation point
of view the above pointer type ('int B::*m') is already capable of
holding the required value (to point to either 'B::a.x' or 'B::z[5]'),
but the language simply has no syntax to assign that value to that
pointer. (It can be done with a hack though).

Your solution with a regular pointer inside 'B' will "work", but suffers
from a number of problems that essentially defeat the purpose in general
case. If it is good enough for the OPs specific case - great. But how
are you going to do it without placing anything into 'B'?

--
Best regards,
Andrey Tarasevich
Jun 28 '08 #23

P: n/a
On Jun 28, 11:50*am, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
alexandrug wrote:
--
Best regards,
Andrey Tarasevich
I wonder if there is a plan to add this "lost" feature in future
standards of c++?
(or maybe i should ask in comp.std.c++ ? )
Jun 28 '08 #24

P: n/a
On Jun 28, 6:50 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
alexandrug wrote:
I'm very happy with the solution. Thank you!
But what if I don't want to increase the size of B?
Then the pointer would not be a member of the class B.

Not a member? How?

Let me illustrate a couple of things by an example. The purpose of
pointer-to-member types is to facilitate nameless selection of class
members (as opposed to named selection we usually use).

For example, consider this code sample

struct A { int a; }

struct B {
int x;
int y;
A a;
int z[10];
};

void zero(B* b, unsigned n, int B::*m) {
for (; n 0; --n, ++b)
b->*m = 0;
}

Now, I can use the above simple 'zero' function I can set to zero any
immediate member of all 'B' objects in an array

B b[10];

zero(b, 10, &B::x); // sets all 'B::x's to zero
zero(b, 10, &B::y); // sets all 'B::y's to zero

Or I can choose what to zero based on some run-time criteria

zero(b, 10, rand() % 2 == 0 ? &B::x : &B::y);

This is the valuable run-time flexibility provided by pointers of
pointer-to-member type (in this case applied specifically to data members).

However, what if I want to zero 'B::a.x' members in the 'b' array? Or
what about zeroing 'B::z[5]' in each element of the 'b' array? In C++
you can't do that. And the truth is that from the implementation point
of view the above pointer type ('int B::*m') is already capable of
holding the required value (to point to either 'B::a.x' or 'B::z[5]'),
but the language simply has no syntax to assign that value to that
pointer. (It can be done with a hack though).

Your solution with a regular pointer inside 'B' will "work", but suffers
from a number of problems that essentially defeat the purpose in general
case. If it is good enough for the OPs specific case - great. But how
are you going to do it without placing anything into 'B'?

--
Best regards,
Andrey Tarasevich
-------------------

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

-------------------

From the initial post, I understood that a member pointer is a data
member of a class,
not a pointer to a member of a class or to anything else. So take my
postings as such.

Alex.
Jun 28 '08 #25

P: n/a
hu*****@gmail.com wrote:
On Jun 28, 11:50 am, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
>alexandrug wrote:
--
Best regards,
Andrey Tarasevich

I wonder if there is a plan to add this "lost" feature in future
standards of c++?
(or maybe i should ask in comp.std.c++ ? )
Ask here or in comp.lang.c++.moderated. c.s.c++ is unfortunately dead
for the time being (multiple inquiries about the reasons have gone
unanswered).

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

P: n/a
Alf P. Steinbach wrote:
* Victor Bazarov:
>hu*****@gmail.com wrote:
>>On Jun 28, 11:50 am, Andrey Tarasevich
<andreytarasev...@hotmail.comwrote:
alexandrug wrote:
--
Best regards,
Andrey Tarasevich
I wonder if there is a plan to add this "lost" feature in future
standards of c++?
(or maybe i should ask in comp.std.c++ ? )

Ask here or in comp.lang.c++.moderated. c.s.c++ is unfortunately
dead for the time being (multiple inquiries about the reasons have
gone unanswered).

Not quite unanswered.

I forwarded an inquiry in comp.lang.c++.moderated about this to two
of the comp.std.c++ moderators, namely the two that last seemed to
be active, and the same day (I think it must be related...) Fergus
replied to that article, as follows:

<url:
http://groups.google.com/group/comp.lang.c++.moderated/msg/52a26fec00939fe5>:

* Fergus Henderson (comp.std.c++ moderator), on Jun 18 2008:
>On Jun 11, 10:39 pm, Joe Gottman <jgott...@carolina.rr.comwrote:
>> It's now been six months sincecomp.std.c++went down.
According to Google Groups the last post was on January 9th. Does
anybody have any information on when it might come back, or
even exactly what went wrong?

The moderation software for comp.std.c++ was hosted on my account
on a machine at the University of Melbourne. The university
removed my account, and I have not found time
to do anything about it. My sincere apologies to all of the users
of comp.std.c++.

My life circumstances have changed quite a bit in the years since I
first volunteered to
run the comp.std.c++ moderation software. Back then I was a
postgrad student with lots of time. Since then, I now have a few
more committments... a job, a wife, a daughter.

If someone else wanted to take on the role, I would be quite happy
to relinquish it.


So, any takers?

It needs some stable company or organization such as a university
that can host the server, one that will most likely continue to
exist for many many years. I don't understand why they haven't
asked Google to do that. But then, I don't know much more than
anyone else about what happened, or didn't
happen.
We can only guess that there must be some very special requirements
for that account, as nobody else has been able to take over the
hosting for six months. Google is a good idea, or MS, or IBM, or
Intel, or HP, or Adobe, or Apple - just to mention a few of the
companies involved.

Can't be lack of hardware, can it? I have a spare PC, if it is...
Bo Persson
Jun 29 '08 #27

P: n/a
Alf P. Steinbach wrote:
* Fergus Henderson (comp.std.c++ moderator), on Jun 18 2008:
>The moderation software for comp.std.c++ was hosted on my account on a
machine at the University of Melbourne. The university removed my
account, and I have not found time
to do anything about it. My sincere apologies to all of the users of
comp.std.c++.
>If someone else wanted to take on the role, I would be quite happy to
relinquish it.

So, any takers?
In the absence of anyone willing to moderate comp.std.c++, perhaps the
group could be made unmoderated until a suitable moderator is found?

I assume only Fergus could perform that switch, since he was the most
recent moderator. Has anyone asked him to do that?
--
Fran
Jun 29 '08 #28

P: n/a
Hi!

Andrey Tarasevich schrieb:
For example, consider this code sample

struct A { int a; }

struct B {
int x;
int y;
A a;
int z[10];
};

void zero(B* b, unsigned n, int B::*m) {
for (; n 0; --n, ++b)
b->*m = 0;
}

Now, I can use the above simple 'zero' function I can set to zero any
immediate member of all 'B' objects in an array

B b[10];

zero(b, 10, &B::x); // sets all 'B::x's to zero
zero(b, 10, &B::y); // sets all 'B::y's to zero
typedef int& (*BIntMember) (B*);

void zero(B*const b, unsigned const n, BIntMember const m) {
for(; n>0; --n, ++b)
m(b) = 0;
}

int& B_x(B*const b) { return b->x; }
int& B_y(B*const b) { return b->y; }
int& B_a_a(B*const b) { return b->a.a; }

B b[10];

zero(b, 10, &B_x);
zero(b, 10, &B_y);
zero(b, 10, &B_a_a);

OR using boost.lambda:

for_each(b, b+10, bind(&B_x, _1) = 0);
for_each(b, b+10, bind(&B_x, _1)++);
....

Frank
Jun 29 '08 #29

P: n/a
In article <uk***********@not.available>, em***@not.available says...

[ ... ]
In the absence of anyone willing to moderate comp.std.c++, perhaps the
group could be made unmoderated until a suitable moderator is found?

I assume only Fergus could perform that switch, since he was the most
recent moderator. Has anyone asked him to do that?
Having been involved (peripherally) in one such switch before, let me be
the first to say that although this initially sounds like a good idea,
it's really not at all.

Moderated newsgroups and unmoderated newsgroups work enough differently
that you can't really change one to the other -- rather, you have to
dismantle the one complete (and make sure it's gone off all servers),
then create a new one of the other type, and wait for it to propagate to
all servers.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 30 '08 #30

P: n/a
On Jun 29, 10:33 pm, Francis Litterio <em...@not.availablewrote:
Alf P. Steinbach wrote:
* Fergus Henderson (comp.std.c++ moderator), on Jun 18 2008:
The moderation software for comp.std.c++ was hosted on my
account on a machine at the University of Melbourne. The
university removed my account, and I have not found time to
do anything about it. My sincere apologies to all of the
users of comp.std.c++. If someone else wanted to take on
the role, I would be quite happy to relinquish it.
So, any takers?
In the absence of anyone willing to moderate comp.std.c++,
perhaps the group could be made unmoderated until a suitable
moderator is found?
I don't think that the problem is just a moderator. Fergus
isn't the only moderator, and (like comp.lang.c++.moderated)
they've added moderators in the past. If I understand Fergus'
post, they've lost the hosting account (machine).

Note that hosting a moderated group is not a trivial
undertaking; you can't do it just because you happen to have a
spare machine. You need very good, reliable network
connectivity. And I'm not sure that Google is in the business
of hosting Usenet groups (as opposed to Google groups).

(Note that the situation with comp.lang.c++.moderated isn't all
that different. David Vandevoorde set it up when he was a
student at RPI, and he's also moved on with a job, wife and
kids. At least to date, however, RPI hasn't removed the account
it runs under:-).)
I assume only Fergus could perform that switch, since he was
the most recent moderator. Has anyone asked him to do that?
From what I understand: once a moderator, always a moderator.
At least officially---not all moderators are necessarily active
at any given time. (When was the last time Robert Martin
moderated a posting to comp.lang.c++.moderated?) In the case of
comp.std.c++, there is, in fact, a group of
moderators---originally three, but others have been added since
then. It should be possible to find a relatively recent list,
and contact them about "adding" someone else. Provided one can
find a good candidate, who also has the time to do it. And
provided one can find a reliable hosting site.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 30 '08 #31

P: n/a
On Jun 30, 4:14*am, James Kanze <james.ka...@gmail.comwrote:
[...]
Note that hosting a moderated group is not a trivial
undertaking; you can't do it just because you happen to have a
spare machine. *You need very good, reliable network
connectivity. *And I'm not sure that Google is in the business
of hosting Usenet groups (as opposed to Google groups).

(Note that the situation with comp.lang.c++.moderated isn't all
that different. *DavidVandevoordeset it up when he was a
student at RPI, and he's also moved on with a job, wife and
kids. *At least to date, however, RPI hasn't removed the account
it runs under:-).)

Right. When I graduated from RPI, I was told that clc++m could
continue to use the CS facilities to host our homegrown moderation set
up. At the time, CS department head was my advisor (and friend), and
the lab director was also a friend. People have moved on since then,
but RPI CS has remained very friendly to us (even though the original
machine has been replaced once or twice since then).

If RPI CS were to decide it cannot host us anymore, I do have an
alternative hosting plan. However, that would require us to rewrite
at least part of the scripts that handle our setup. Even assuming RPI
continues to provide us with a machine, we'll likely have to face that
problem sooner or later, since our scripts rely on not-so-modern mail
and usenet tools. (We also owe much to John Potter who has been
fixing the scripts as bugs were detected and as the environment has
changed over the years.)

Daveed

Jun 30 '08 #32

This discussion thread is closed

Replies have been disabled for this discussion.