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. ]