Topic: What is the actual type of a pointer-to-member?


Author: John Max Skaller <maxtal@suphys.physics.su.oz.au>
Date: 1995/12/06
Raw View
Peter Hubel <ludvig@daimi.aau.dk> wrote:
>
>I have a question regarding pointers-to-members.
>Given these two classes:
>
>  struct B {
>    int b;
>  }
>
>  struct D : public B {
>    int d;
>  };
>
>Will the type of the expression '&D::b' be 'int D::*' or 'int B::*'?

   int B::*

 -- which I personally regard as a SERIOUS blunder.

>What I'd like is that '&D::b' is of type 'int D::*' whereas '&B::b' is of
>type 'int B::*'.

I agree completely. But it is not the case. You must write:

  (int D::*)&B::b //or
  static_cast<int D::*>(&B::b)

Even worse, the pointer to member system is functionally
incomplete: there's no way to add two pointers to members.
Hence it is impossible to navigate a membership tree.

I have some templates called TypedOffset<Class, Member>
which provide a complete algebra suitable for implementing
meta-classes -- but I can't support inheritance conversions
(at least not without member templates); nor functions.
[alpha testers and designers welcome, please email me]

--
John Max Skaller               voice: 61-2-566-2189
81 Glebe Point Rd              fax:   61-2-660-0850
GLEBE NSW 2037                 email: maxtal@suphys.physics.oz.au
AUSTRALIA                      email: skaller@maxtal.com.au




---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: Peter Hubel <ludvig@daimi.aau.dk>
Date: 1995/12/01
Raw View
I have a question regarding pointers-to-members.

Given these two classes:

  struct B {
    int b;
  }

  struct D : public B {
    int d;
  };

Will the type of the expression '&D::b' be 'int D::*' or 'int B::*'?

Both answers make sense in some way, but the Standard seems not to
clarify whether the one or the other is right. Or both are.

What I'd like is that '&D::b' is of type 'int D::*' whereas '&B::b' is of
type 'int B::*'.

I've created a little template function to check out what my compilers
think about the matter:

  template <class C, class M> // class, member
  ostream& operator<<(ostream& os, M C::*ptm)
  {
    os << typeid(M).name() << ' ' << typeid(C).name() << "::*ptm";
    return os;
  }

Now both Borland and Microsoft compilers use the
'point of declaration':

  cout << (&D::b) << endl; // displays 'int B::*'


This is a problem to me... I'm working on a project using a lot of
this 'meta-information' in form of pointer-to-members. To give you
an idea I have something like

  template <class T>
  class Member {
  // Class for describing a member of class T
  public:
    Member(const char* name, size_t sz);
    ...
  private:
    const char* name_;
    size_t sz_;
  };

  template <class T>
  class MetaClass<T> {
  // MetaClass for class T
  ...
    void AddMember(Member<T> member);
  private:
    List<Member<T> > members_;
  ...
  };

Now I'd like to use template functions to perform type inference
(please don't mind the silly example):

  template <class C, class M>
  Member<C> CreateMember(M C::*ptm, const char* name)
  {
    return Member<C>(name, sizeof(M));
  }

Alas, it don't work:

  MetaClass<D> meta_d;

  meta_d.AddMember(CreateMember(&D::d, "&D::d")); // ok
  meta_d.AddMember(CreateMember(&D::b, "&D::b")); // error

The second call returns a 'Member<B>' and the function expects
a 'Member<D>' and there is no is-a relation between the template
instances, even if D is-a B... We don't have co-variance in C++,
remember?

It somehow bothers me, when I actually write '&D::b',
and the compiler otherwise recognizes the expression as a valid
pointer-to-member, that the thing won't acknowledge that 'b' is
a (well, inherited, but anyway) member of 'D' and infere the
appropriate type.

"I wrote 'D', and I meant it, silly!" - but then again, have I missed
something?

Any comments on this would be welcome.

--peter



---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]