|  | operator > Against Addresses Of Member Functions |  | |
| | | Le Chaud Lapin |  |
| Posted: Mon Sep 01, 2008 7:14 am Post subject: operator > Against Addresses Of Member Functions |  |
Hi All,
What's the preferred method for ascertaining truth of
p1 > p2
when p1 and p2 are both pointers to potentially different member functions of the same concrete class?
I could obviously do a memcmp (p1, p2, sizeof(p1)), but that might lead to different ordering on different platforms, which, at present, is not a problem for me, but still makes me uneasy.
-Le Chaud Lapin-
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Jiang |  |
| Posted: Mon Sep 01, 2008 10:19 am Post subject: Re: operator > Against Addresses Of Member Functions |  |
On Sep 1, 4:14 pm, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
| Quote: | Hi All,
What's the preferred method for ascertaining truth of
p1 > p2
when p1 and p2 are both pointers to potentially different member functions of the same concrete class?
I could obviously do a memcmp (p1, p2, sizeof(p1)), but that might lead to different ordering on different platforms, which, at present, is not a problem for me, but still makes me uneasy.
|
No, there is no way to do the comparison correctly, since the behavior for above comparison is unspecified by the current standard(In 5.9/p2). Also I do not see the point for this kind of comparison.
BTW, the internal implementation for pointer-to-memfun can be even a struct, so it is quite possible compilers will reject the above code.
Jiang
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Maxim Yegorushkin |  |
| Posted: Mon Sep 01, 2008 10:58 am Post subject: Re: operator > Against Addresses Of Member Functions |  |
| |  | |
On Sep 1, 8:14 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
| Quote: | Hi All,
What's the preferred method for ascertaining truth of
p1 > p2
when p1 and p2 are both pointers to potentially different member functions of the same concrete class?
I could obviously do a memcmp (p1, p2, sizeof(p1)), but that might lead to different ordering on different platforms, which, at present, is not a problem for me, but still makes me uneasy.
|
One way to do this is to use regular functions as adapters and compare the addresses of those adapters:
struct X { void f(); void g(); };
// adapters void f(X* that) { that->f(); } void g(X* that) { that->g(); }
int main() { return f > g; }
A function template could be used as an adapter as well:
template<void(X::*mem_fun)()> void adapter(X* that) { (that->*mem_fun)(); }
int main() { return adapter<&X::f> < adapter<&X::g>; }
-- Max
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Marco Manfredini |  |
| Posted: Mon Sep 01, 2008 7:58 pm Post subject: Re: operator > Against Addresses Of Member Functions |  |
Le Chaud Lapin wrote:
| Quote: | I could obviously do a memcmp (p1, p2, sizeof(p1)), but that might lead to different ordering on different platforms, which, at present, is not a problem for me, but still makes me uneasy.
|
It might even lead to different ordering on each program invocation on the same platform, because the runtime linker is, apart from certain requirements on pointer equality, free to construct the text segment as it deems it best. A non-broken Address Space- and Load Order Randomization will most likely change the "order" of member function pointers.
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Martin Bonner |  |
| Posted: Mon Sep 01, 2008 7:58 pm Post subject: Re: operator > Against Addresses Of Member Functions |  |
On Sep 1, 8:14 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
| Quote: | Hi All,
What's the preferred method for ascertaining truth of
p1 > p2
when p1 and p2 are both pointers to potentially different member functions of the same concrete class?
I could obviously do a memcmp (p1, p2, sizeof(p1)), but that might lead to different ordering on different platforms, which, at present, is not a problem for me, but still makes me uneasy.
|
std::greater<typeof(p1)>()( p1, p2 )
20.3.3 p8 says "For templates greater ... the specializations for any pointer type yield a total order, even if the built-in operators ... do not.
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Greg Herlihy |  |
| Posted: Mon Sep 01, 2008 7:58 pm Post subject: Re: operator > Against Addresses Of Member Functions |  |
| |  | |
On Sep 1, 3:19 am, Jiang <goo.mai...@yahoo.com> wrote:
| Quote: | On Sep 1, 4:14 pm, Le Chaud Lapin <jaibudu...@gmail.com> wrote: What's the preferred method for ascertaining truth of
p1 > p2
when p1 and p2 are both pointers to potentially different member functions of the same concrete class?
No, there is no way to do the comparison correctly, since the behavior for above comparison is unspecified by the current standard(In 5.9/p2). Also I do not see the point for this kind of comparison.
|
Even though the comparison operators may not provide a total ordering when comparing pointers, it is nonetheless possible to order any set of pointers by using the std::less (or greater, greater_equal, or less_equal) template for the comparison. The problem in this case is that member function pointers - are not actually pointers; so there is no C++ language or library support for performing ordered comparisons of member pointers directly.
| Quote: | BTW, the internal implementation for pointer-to-memfun can be even a struct, so it is quite possible compilers will reject the above code.
|
One could use templates to instantiate function "proxies" for the member pointers and then compare the function pointers as described above (see this c.l.c++.m post for an example):
LINK
Greg
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Le Chaud Lapin |  |
| Posted: Mon Sep 01, 2008 9:59 pm Post subject: Re: operator > Against Addresses Of Member Functions |  |
| |  | |
On Sep 1, 5:19 am, Jiang <goo.mai...@yahoo.com> wrote:
| Quote: | On Sep 1, 4:14 pm, Le Chaud Lapin <jaibudu...@gmail.com> wrote: What's the preferred method for ascertaining truth of
p1 > p2 No, there is no way to do the comparison correctly, since the behavior for above comparison is unspecified by the current standard(In 5.9/p2). Also I do not see the point for this kind of comparison.
|
I guess I should provide some context for discussion.
In the sentence:
"Water is wet."
"Water" is the subject, and "is wet" is the predicate. The predicate consists of the verb "is" and object "wet". I need to maintain the "is wet" part as an object that can be assigned, serialized, stored in set<>, map<>, etc. I construct this predicate in a Relational_Predicate<>:
template <typename Element> struct Relational_Predicate { typedef bool (Element::*Relation) (const Element &object) const;
Relation relation; Element object;
Relational_Predicate (Relation relation, const Element &object) : relation(relation), object(object) {}
bool complements (const Element &subject) const { return (subject.*relation)(object); } // ...lot of other stuff } ;
I have several classes that naturally lend themselves to this concept:
struct Space { bool operator == (const Space &) const; bool operator != (const Space &) const; bool operator > (const Space &) const; bool operator < (const Space &) const; bool operator >= (const Space &) const; bool operator <= (const Space &) const; bool is_subspace_of (const Space &) const; bool is_proper_subspace_of (const Space &) const; bool is_superspace_of (const Space &) const; bool is_proper_superspace_of (const Space &) const; } ;
I take two of these objects, say, s1, and s2, plus a relation r, between them. I intend to test:
s1 r s2; // True or False?
I store the relation r and s2 together as a relational predicate rp. I can then apply rp to any subject s1 to see if rp complements s1:
int main () { Space s1, s2;
Relational_Predicate<Space> rp(&Space::is_proper_subspace_of, s2);
if (rp.complements(s1)) cout << "s1 is proper subspace of s2"; else cout << "s1 is not proper subspace of s2";
return 0; }
There are many places in my project where I need to do this, where I have a class that closely resembles Space in form - it is concrete and contains 10-20 member function with identical signatures, each const, taking by const reference one of its kind and returning bool. The member functions are typically a combination of traditonal relational operators (==, !=, >, <, etc.), plus similar functions written in text (when there are not enough overloadable C++ operators). As mentioned earlier, I need to store the relational predicates in containers, so a comparison < between two Relational_Predicate<>'s is necessary.
Right now, I have a static table of pointers to member functions that is declared by Relational_Predicate<>, but defined by the code for the class {} argument to Relational_Predicate. From this table, I can find the index of a member function of class {}, and when I need to compare two Relational_Predicate<> objects, I compare subject of the relational predicate directly, but for the relation, I compare not the relation itself but the index of the relation as determined from the table. This method is stable accross platforms since the table is constructed by the library designer (me). But for speed, this method requires that the index be cached in each Relational_Predicate<> object, an overhead of say 1 or 2 bytes. Otherwise, during comparison inside a container, a lookup into the table will be necessary each time, which turns out to be unacceptable for my project.
Your note about member functions possibly being struct's makes me almost certain that I will avoid memcmp tricks on the pointer and just use the cached index method.
-Le Chaud Lapin-
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Le Chaud Lapin |  |
| Posted: Tue Sep 02, 2008 4:41 am Post subject: Re: operator > Against Addresses Of Member Functions |  |
On Sep 1, 2:58 pm, Greg Herlihy <gre...@mac.com> wrote:
| Quote: | One could use templates to instantiate function "proxies" for the member pointers and then compare the function pointers as described above (see this c.l.c++.m post for an example):
LINK
|
Interesting trick.
I failed to mention that my design-space is run-time-oriented, where for class C, I have is an instance of C and a member function of C, together as a unit.
mem_fun and c2 are stored in a Relational_Predicate<> object, of which I have several hundred (or more), and I need to iteratively bind c1 to each [mem_func, c2] object to yield true/false.
-Le Chaud Lapin-
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Jiang |  |
| Posted: Tue Sep 02, 2008 7:41 pm Post subject: Re: operator > Against Addresses Of Member Functions |  |
| |  | |
On Sep 2, 4:58 am, Greg Herlihy <gre...@mac.com> wrote:
| Quote: | On Sep 1, 3:19 am, Jiang <goo.mai...@yahoo.com> wrote:
|
[...]
| Quote: | BTW, the internal implementation for pointer-to-memfun can be even a struct, so it is quite possible compilers will reject the above code.
One could use templates to instantiate function "proxies" for the member pointers and then compare the function pointers as described above (see this c.l.c++.m post for an example):
LINK
|
Thanks for the pointer, but I failed to see why the proposed wrapper can do the ranking job. What I see is you built a one-to-one relationship and further made the comparison safe, but how can I get the original rank/order information?
BTW, the above code won't compile by como under strict mode, even I added the necessary include file and definitions.
-----------------------------------------------------
$ como --A mfc.cpp Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors [microsoft] C++ noC++0x_extensions
"mfc.cpp", line 26: error: expression must have (pointer-to-) function type &t->*mf(); ^
1 error detected in the compilation of "mfc.cpp".
-----------------------------------------------------
Maybe you can verify this by comeau online.
Regards,
Jiang
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Seungbeom Kim |  |
| Posted: Wed Sep 03, 2008 8:28 am Post subject: Re: operator > Against Addresses Of Member Functions |  |
| |  | |
Jiang wrote:
| Quote: | BTW, the above code won't compile by como under strict mode, even I added the necessary include file and definitions.
-----------------------------------------------------
$ como --A mfc.cpp Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors [microsoft] C++ noC++0x_extensions
"mfc.cpp", line 26: error: expression must have (pointer-to-) function type &t->*mf(); ^
1 error detected in the compilation of "mfc.cpp".
-----------------------------------------------------
|
An additional pair of parentheses helps:
(&t->*mf)();
Interestingly enough, you don't need one around "&t" here; on the other hand, in case of "->" instead of "->*", you need one around "&t", not around the whole "->" expression: "(&t)->f();"
-- Seungbeom Kim
[ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
|
|