Calling member function using a smart pointer and a pointer to member function

Calling member function using a smart pointer and a pointer to member function

Post by Howard Gar » Thu, 03 Feb 2005 05:01:57


*
Victory!

This version:

1) does not intrude on either example or ptr<>.
2) depends only on ptr<> having an operator->() defined.
3) gets me to the temporary's lifetime benefit.

I can retrofit other people's smart pointers this way!

I think that this solution is valid for calling any member function that
takes zero parameters, and feel confident that I can extend it to cover
higher arities (my library, The UFO, is only concerned with arities up
to 3 at this point).
*/

#include <iostream>
using namespace std;

// Some random class that has a member function
struct example
{
int mem_func() const
{cout << "example::mem_func" << endl; return 42;}
};

// A deliberately minimalist "smart pointer"
template
<
typename xPointee,
typename xPointer = xPointee *,
typename xStorage = xPointee *
struct ptr
{
typedef ptr tSelf;
typedef xPointee tPointee;
typedef xPointer tPointer;
typedef xStorage tStorage;

ptr(const tSelf & fThat)
:cStorage(fThat.cStorage)
{}

explicit
ptr(tPointee * fThat)
:cStorage(fThat)
{}

~ptr()
{}

tPointer operator ->() const
{return tPointer(cStorage);}

tStorage cStorage;
};

// A nullary functor to be returned by overloaded global operator ->*
template < typename xPtr, typename xPtrMemFunc, typename xResult >
struct proxy
{
typedef proxy tSelf;
typedef xPtr tPtr;
typedef xPtrMemFunc tPtrMemFunc;
typedef xResult tResult;

proxy(const tPtr & fPtr, tPtrMemFunc fPtrMemFunc)
: cPtr(fPtr), cPtrMemFunc(fPtrMemFunc)
{}

~proxy()
{}

tResult operator()() const
{
// This line is critical for 2 reasons
// 1. It allows "ptrs returning ptrs returning ..." to work
// 2. It gets me to the temporary's lifetime benefit
return call(cPtr.operator->(), cPtrMemFunc);
}

const tPtr & cPtr;
tPtrMemFunc cPtrMemFunc;
};

// overloaded global operator ->*
template < typename xPtr, typename xResult, typename xClass >
proxy< xPtr, xResult (xClass::*)() const, xResult >
operator ->*(const xPtr & fPtr, xResult (xClass::*fPtrMemFunc)() const)
{
typedef xPtr tPtr;
typedef xResult tResult;
typedef xResult (xClass::*tPtrMemFunc)() const;
typedef proxy< tPtr, tPtrMemFunc, tResult > tProxy;
return tProxy(fPtr, fPtrMemFunc);
}

// Call a member function with either a pointer or a smart pointer
template < typename xPtr, typename xResult, typename xClass >
xResult
call(xPtr fPtr, xResult (xClass::*fPtrMemFunc)() const)
{
// If used on a real pointer, this does just what it appears to do.
// If used on a ptr<>, this first calls the overloaded global
// operator ->*, then immediately calls operator () on the proxy that
// was returned.
return (fPtr->*fPtrMemFunc)();
}

int main()
{
example fExample;

cout << "real pointers work" << endl;
cout << call(&fExample, &example::mem_func) << endl;
cout << endl;

cout << "simple smart pointers work" << endl;
typedef ptr< example > tSimple;
tSimple fSimple(&fExample);
cout << call(fSimple, &example::mem_func) << endl;
cout << endl;

cout << "more complex smart pointers work" << endl;
typedef ptr< example, ptr< example, ptr< exam
 
 
 

1. Better way to call member function using function pointer?

2. Pointer-to-member-function pointing to a member function of an inherited class

The subject basically says what I am having trouble with. For an
example lets say I have a class A which has a function f. I then also
have a class B which inherits from A and has a function g.

class A
{
public: void f(int,float);
};

class B : public A
{
public: void g(int, float);
};


Okay, now with all that setup, if I created a pointer to a member
function something like this:

typedef void (A::*MFP)(int a, float b);

if I then use it such as

MFP mfp = &A::f;

then everything works fine.

even if I do:

MFP mfp2 = &B::f;

then everything still works (presumably because f is not defined in B
and must then be from A). However, if I try this:

MFP mfp3 = &B::g;

then it complains that B::g is not of the right type since it is not a
member function of class A. The protype signature is the same, both
(int, float), is there no way to make this work? It seemed to me that
it should have worked since any instance of B is still by definition an
instance of A. Anyone done anything like this?

-akiriwas

3. static member functions vs. member function pointers

4. Passing pointer to member function as template parameter to member function of another class

5. Passing pointer to member function as template parameter to member function of another class

6. Pointer to a pointer to a pointer to a member function

7. function pointer and member function pointer question

8. Member function pointers to member functions with default arguments

9. pointers to functions and pointers to static member functions

10. Pointer-to-member-function pointing to a member function of an i

11. Elegant solution for pointer-to-a virtual member function to function pointer

12. Passing pointer to member function as template parameter to member function of another class

13. pointer to member conversion to a pointer to member that is a member's base class

14. Fwd: pointer to member conversion to a pointer to member that is a member's base class