🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #2813

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

#2813
From: Peter Hubel
Date: Fri, 01 Dec 1995 05:12
102 lines
3044 bytes
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. ]
Technical Details
Message-ID: <01BABB82.F5809FE0@default>
Path: arc1-ca.pugleaf.net!howland.reston.ans.net!agate!agate!Matt

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!howland.reston.ans.net!agate!agate!Matt
From: Peter Hubel <ludvig@daimi.aau.dk>
Newsgroups: comp.std.c++
Subject: What is the actual type of a pointer-to-member?
Date: 01 Dec 1995 05:12:41 GMT
Organization: <none>
Approved: Matt@Austern
Message-ID: <01BABB82.F5809FE0@default>
NNTP-Posting-Host: austern.hip.berkeley.edu