pointer to a member of a member

Discussion in 'C++' started by huili80@gmail.com, Jun 27, 2008.

  1. Guest

    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, 2008
    #1
    1. Advertising

  2. 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, Jun 27, 2008
    #2
    1. Advertising

  3. Victor Bazarov wrote:
    > n2xssvv.g02gfr12930 wrote:
    >> 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
    n2xssvv.g02gfr12930, Jun 27, 2008
    #3
  4. Greg Herlihy Guest

    On Jun 27, 10:42 am, Victor Bazarov <> wrote:
    > 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
    Greg Herlihy, Jun 27, 2008
    #4
  5. Guest

    On Jun 27, 3:00 pm, Victor Bazarov <> wrote:
    > Greg Herlihy wrote:
    > > On Jun 27, 10:42 am, Victor Bazarov <> wrote:
    > >> 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; }
    const double& operator[] (int i) const { return this->*_v; }
    };
    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, 2008
    #5
  6. Guest

    On Jun 27, 3:33 pm, wrote:
    > On Jun 27, 3:00 pm, Victor Bazarov <> wrote:
    >
    >
    >
    > > Greg Herlihy wrote:
    > > > On Jun 27, 10:42 am, Victor Bazarov <> wrote:
    > > >> 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; }
    >     const double& operator[] (int i) const { return this->*_v; }};
    >
    > 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, 2008
    #6
  7. Guest

    On Jun 27, 4:04 pm, Victor Bazarov <> wrote:
    > wrote:
    > > On Jun 27, 3:33 pm, wrote:
    > >> On Jun 27, 3:00 pm, Victor Bazarov <> wrote:

    >
    > >>> Greg Herlihy wrote:
    > >>>> On Jun 27, 10:42 am, Victor Bazarov <> wrote:
    > >>>>> 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; }
    > >>     const double& operator[] (int i) const { return this->*_v; }};

    >
    > >> 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, 2008
    #7
  8. Hi!

    Apart from what Victor says:

    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
    Frank Birbacher, Jun 27, 2008
    #8
  9. Guest

    On Jun 27, 6:32 pm, Frank Birbacher <> wrote:
    > Hi!
    >
    > Apart from what Victor says:
    >
    > 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, 2008
    #9
  10. 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
    Andrey Tarasevich, Jun 28, 2008
    #10
  11. Guest

    On Jun 27, 9:09 pm, Andrey Tarasevich <>
    wrote:
    > 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, 2008
    #11
  12. Greg Herlihy Guest

    On Jun 27, 12:45 pm, 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
    Greg Herlihy, Jun 28, 2008
    #12
  13. James Kanze Guest

    On Jun 28, 12:32 am, Frank Birbacher <> wrote:

    [...]
    > 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:
    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
    James Kanze, Jun 28, 2008
    #13
  14. alexandrug Guest

    On Jun 27, 7:47 pm, 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;
    }
    alexandrug, Jun 28, 2008
    #14
  15. Guest

    On Jun 28, 8:07 am, alexandrug <> wrote:
    > On Jun 27, 7:47 pm, 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, 2008
    #15
  16. alexandrug Guest

    On Jun 28, 4:45 pm, wrote:
    > On Jun 28, 8:07 am, alexandrug <> wrote:
    >
    >
    >
    > > On Jun 27, 7:47 pm, 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.
    alexandrug, Jun 28, 2008
    #16
  17. Guest

    On Jun 28, 11:50 am, Andrey Tarasevich <>
    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, 2008
    #17
  18. alexandrug Guest

    On Jun 28, 6:50 pm, Andrey Tarasevich <>
    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.
    alexandrug, Jun 28, 2008
    #18
  19. Bo Persson Guest

    Re: comp.std.c++ update [was: pointer to a member of a member]

    Alf P. Steinbach wrote:
    > * Victor Bazarov:
    >> wrote:
    >>> On Jun 28, 11:50 am, Andrey Tarasevich
    >>> <> 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).

    >
    > 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 <> wrote:
    >>
    >>> 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
    Bo Persson, Jun 29, 2008
    #19
  20. 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
    Frank Birbacher, Jun 30, 2008
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fraser Ross
    Replies:
    4
    Views:
    1,044
    Fraser Ross
    Aug 14, 2004
  2. Replies:
    10
    Views:
    698
    Chris Torek
    Feb 4, 2005
  3. Stephen Howe
    Replies:
    2
    Views:
    288
    Stephen Howe
    Nov 6, 2012
  4. somenath
    Replies:
    10
    Views:
    279
    James Kanze
    Jul 2, 2013
  5. somenath
    Replies:
    2
    Views:
    156
    somenath
    Aug 29, 2013
Loading...

Share This Page