Topic: Comparing member function "pointers
Author: pdimov@mmltd.net (Peter Dimov)
Date: Tue, 25 Sep 2001 23:22:07 GMT Raw View
"Conrad Weyns" <weyns@online.no> wrote in message news:<9ope3e$gtf$1@news1.c.no1.asap-asp.net>...
[...]
> I realize I am on thin ice now and should attempt to find a completely
> different way of approaching this problem.
> I work part time on an application where we have hundreds of Link objects
> containing a T* and a long (T::*:pmf)(void*) member as the second halv of a
> pair used as key in a map: std::map<std::pair<std::string, Link>, long>.
This snippet may be of some use to you, assuming that the compiler can
handle it:
struct T
{
void f();
void g();
};
template<void (T::*pmf)()> struct X
{
static int i;
static void f(T * t) { return (t->*pmf)(); }
};
template<void (T::*pmf)()> int X<pmf>::i;
int main()
{
&X<&T::f>::i < &X<&T::g>::i;
&X<&T::f>::f < &X<&T::g>::f;
}
[ Note: by all means use std::less for the pointer comparisons, this
being comp.std.c++ ;-) ]
--
Peter Dimov
Multi Media Ltd.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Conrad Weyns" <weyns@online.no>
Date: Sun, 23 Sep 2001 12:50:10 GMT Raw View
A pointer to a member function is a mystical creature.
Depending on the platform and the compiler they may or may not be 32 bit
addresses to actual function code. They are in MS VC 6, but in Metrowerks
CodeWarrior they are represented by a struct containing delta, vtbl offset
and func address members, very much to be considered an opaque struct.
The problem is, they can only be tested for equality.
So how can I, in a portable way, use a pointer to a member function as a key
in a std::map without resorting to raw hacks for every single platform and
compiler options?
Why is it so difficult (or not allowed by the standard) for a compiler to
supply a less than operator?
Conrad Weyns,
Norway.
weyns@online.no
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Steve Clamage <clamage@eng.sun.com>
Date: Mon, 24 Sep 2001 15:26:56 GMT Raw View
On Sun, 23 Sep 2001, Conrad Weyns wrote:
> A pointer to a member function is a mystical creature.
> Depending on the platform and the compiler they may or may not be 32 bit
> addresses to actual function code. They are in MS VC 6, but in Metrowerks
> CodeWarrior they are represented by a struct containing delta, vtbl offset
> and func address members, very much to be considered an opaque struct.
>
> The problem is, they can only be tested for equality.
>
> So how can I, in a portable way, use a pointer to a member function as a key
> in a std::map without resorting to raw hacks for every single platform and
> compiler options?
>
> Why is it so difficult (or not allowed by the standard) for a compiler to
> supply a less than operator?
A pointer-to-member-function can point to a virtual function, in which
case it must resolve to the version of the function associated with
the object applied to the pointer dereference.
The pointer therefore cannot in general carry an address, but for a
virtual function would contain information on how to find the function
address.
What wold "less than" mean for structure types containing information
about finding a function address that cannot be resovled at the point
of the comparison? It's not obvious to me that you could define an
ordering that would be transitive (a<b and b<c implies a<c).
--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Just me <not@so.silly>
Date: Mon, 24 Sep 2001 16:41:55 GMT Raw View
"Conrad Weyns" ha scritto:
> So how can I, in a portable way, use a pointer to a member function as
> a key in a std::map without resorting to raw hacks for every single
> platform and compiler options?
I'm not sure, but could one compare the _pointer_ address, specializing
std::less on the specific pointer to member type?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Sergey P. Derevyago" <non-existent@iobox.com>
Date: Mon, 24 Sep 2001 17:27:41 GMT Raw View
Steve Clamage wrote:
> What wold "less than" mean for structure types containing information
> about finding a function address that cannot be resovled at the point
> of the comparison?
IMHO such "less than" operation can behave just like
std::type_info::before().
> It's not obvious to me that you could define an
> ordering that would be transitive (a<b and b<c implies a<c).
AFAIK in some implementation we can use memcmp() in order to define the
ordering in question.
--
With all respect, Sergey. http://cpp3.virtualave.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Conrad Weyns" <weyns@online.no>
Date: Mon, 24 Sep 2001 19:44:37 GMT Raw View
"Steve Clamage" <clamage@eng.sun.com> wrote in message
news:Pine.SOL.4.33.0109230937350.9162-100000@taumet...
> On Sun, 23 Sep 2001, Conrad Weyns wrote:
>
> > A pointer to a member function is a mystical creature.
[...]
> > Why is it so difficult (or not allowed by the standard) for a compiler
to
> > supply a less than operator?
>
> A pointer-to-member-function can point to a virtual function, in which
> case it must resolve to the version of the function associated with
> the object applied to the pointer dereference.
>
I understand this issue very well but for all pratical purposes that I have
encountered, I don't believe that it matters. It is also inconsistent with
the availability of the equality operator.
> The pointer therefore cannot in general carry an address, but for a
> virtual function would contain information on how to find the function
> address.
>
> What wold "less than" mean for structure types containing information
> about finding a function address that cannot be resovled at the point
> of the comparison?
Returning whatever is practically feasible from the information available at
the point of comparison is bether than nothing. For all I care, the compiler
can use the vtbl offset.
class CObject
{
public:
void f1(void*);
virtual void f2(void*);
virtual void f3(void*);
};
typedef void (CObject::*TObjFunc)(void*);
TObjFunc pf1 = CObject::f1;
TObjFunc pf2 = CObject::f2;
TObjFunc pf3 = CObject::f3;
At this stage, one could argue that pf2 and pf3, being virtual, don't make
much sence without some CObject instance or derivative. Yet it is perfectly
legal to write:
if (pf2 == pf3)
Whether the comparison
if (pf2 < pf3)
should return true or false, does not realy matter, as long as it is
consistant. Since in neither of these 2 cases, there is yet any object
instance involved, the mechanics are identical.
If "less than" is illegal, then testing for equality should be just as
illegal as once an object instance is involved, it could be just as wrong.
In fact it could be argued that comparing two pointers to member functions
should not be doable without the direct involment of two object instances.
Eventhough one would have to be very aware of the mechanics and limitations
of a less than operator, I think its presence would by far outway the low
level hacks that we are having to resort to because of its absence.
Regards,
Conrad Weyns.
> It's not obvious to me that you could define an
> ordering that would be transitive (a<b and b<c implies a<c).
>
> --
> Steve Clamage, stephen.clamage@sun.com
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Mon, 24 Sep 2001 16:11:52 CST Raw View
"Sergey P. Derevyago" wrote:
> AFAIK in some implementation we can use memcmp() in
> order to define the
> ordering in question.
A bit-by-bit comparison of the entire data structure may not
be meaningful. Alignment issues may produce a structure with
unallocated space.
The right answer here is to define "<" for the class
used by Metrowerks to describe pointers to function members.
John Nagle
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Barry Margolin <barmar@genuity.net>
Date: Mon, 24 Sep 2001 21:15:02 GMT Raw View
In article <9oo2c6$lj9$1@news1.c.no1.asap-asp.net>,
Conrad Weyns <weyns@online.no> wrote:
>If "less than" is illegal, then testing for equality should be just as
>illegal as once an object instance is involved, it could be just as wrong.
There are many things for which equality testing is valid but relational
comparisons make no sense. For instance, you can't do p<q when p and q are
pointers into different objects (well, you can do it but the results are
not defined), but you can still do p==q.
--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Conrad Weyns" <weyns@online.no>
Date: Tue, 25 Sep 2001 11:31:05 GMT Raw View
"Barry Margolin" <barmar@genuity.net> wrote in message
news:6lNr7.18$AR6.4148@burlma1-snr2...
> In article <9oo2c6$lj9$1@news1.c.no1.asap-asp.net>,
> Conrad Weyns <weyns@online.no> wrote:
> >If "less than" is illegal, then testing for equality should be just as
> >illegal as once an object instance is involved, it could be just as
wrong.
>
> There are many things for which equality testing is valid but relational
> comparisons make no sense. For instance, you can't do p<q when p and q
are
> pointers into different objects (well, you can do it but the results are
> not defined), but you can still do p==q.
>
Yes, I see your point.
After letting this linger during the night, it became clearer that there is
more to it than meets the eye - well, my aging eye at least!
I think the issue arises largely because of what I have encountered having
to do with these creatures.
It would never occur to me to attempt to compare 2 pmf of different classes.
As you pointed out, testing for equality between to such pointers is
actually legal - my two compilers thinks so any way which I must admid, it
surprised me. (All the things I don't know about, it's depressing!)
I think it would still be usefull for the compiler to supply a less than
operator based on the actual address of the function in the declaring class,
simply disregarding virtualness. In CodeWarrior's case, the struct should
also carry this address if only for comparison purposes. (I can see that for
virtual functions it does not do so).
I realize I am on thin ice now and should attempt to find a completely
different way of approaching this problem.
I work part time on an application where we have hundreds of Link objects
containing a T* and a long (T::*:pmf)(void*) member as the second halv of a
pair used as key in a map: std::map<std::pair<std::string, Link>, long>.
In MS VC6 the "bool Link::operator <(const Link& rhs) const" is an uggly
hack that works (for the time being) but that I am having trouble porting
this without causing a lot of noise.
So, back to the drawing board!
Thanks for every one's input here. I havn't yet pondered upon Sergey's
std::type_info::before() idea.
Regards,
Conrad Weyns.
> Barry Margolin, barmar@genuity.net
> Genuity, Woburn, MA
[...]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]