Re: is it possible to get a unique key for a (instance, method) pair?
t.lehmann@rtsgroup.net wrote:
In the example I'm trying to store a (instance, method) pair
as key in a map, but I'm failing because of a comparison "<"
in the "std::pair"! (code after dashed line in example)
2) Why do I want have this key? .....
- - -> 3) Problem:
- - -
I'm trying to avoid attaching twice the same (instance,method) pair to
the same subject wrapped by different command objects (Wrapper0 in
given example). Therefore I tried to use a map - see 1) and see
example!
#include <assert.h>
#include <iostream>
#include <map>
class X
{
public:
void test1() {std::cout << "X::test1" << std::endl;}
void test2() {std::cout << "X::test2" << std::endl;}
};
int main()
{
X x1;
X x2;
Wrapper meth1 = make_wrapper(&x1, &X::test1);
meth1->execute();
Wrapper meth2 = make_wrapper(&x1, &X::test2);
meth2->execute();
Wrapper meth3 = make_wrapper(&x2, &X::test1);
assert( meth1->isEqual(meth3.get()));
assert(!meth1->isEqual(meth2.get()));
The key to ranking the member function pointers safely - is to wrap
each one in a wrapper object and to always wrap the same member pointer
in the same wrapper object. Because once a direct one-to-one
correspondence between member pointers and wrapper object instances has
been established - then simply comparing the addresses of two wrapper
objects (with std::less()) would be all that is needed to be able to
make safe, and totally ordered comparisons between any two member
function pointers.
For example:
template < class T >
struct Wrapper
{
typedef void (T::*Simple_Method)();
// static factory method
template < Simple_Method SM >
static Wrapper* Get()
{
static Wrapper sWrapper(SM);
return &sWrapper;
}
// less than comparison
bool operator<( const Wrapper& rhs ) const
{
return std::less<Wrapper>()( this, &rhs );
}
// invoke wrapped member function
void operator()( T& t)
{
&t->*mf();
}
private:
Wrapper(Simple_Method inMF) : mf(inMF) {}
Simple_Method mf;
};
typedef Wrapper<X> WrapperX, * WrapperXPtr;
int main()
{
WrapperXPtr testOne = WrapperX::Get< &X::test1 >();
WrapperXPtr testTwo = WrapperX::Get< &X::test2 >();
testOne < testTwo; // OK
}
Essentially, a wrapper object would replace the member function pointer
within the the std::pair in the original program.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]