Re: Why pointer to member function?

From: Ben (ben_yu_at_asc.aon.com)
Date: 06/11/04


Date: 10 Jun 2004 21:42:17 -0700

Jeff,
Thanks for refering me to this nice article.

boost function does look clean and powerful. I have no doubt about the
usefulness of this lib.

However, it does not answer my question.

Let me rephrase my question and reasoning:

I want a simple,clean,cheap way that can save the member function
closure into a vector, which implies that the element size has to be
fixed for any type of closure.

And because of the following 2 reasons, it is not possible to save a
ptm INLINE in a vector:

1. pointers to member function don't have the same size and the
maximum size cannot be even predictable.

2. don't want to save a pointer to a pointer to a member function
because a pointer to a member function is normally a constant.

the boost lib does prove that I'm not wrong on this. It uses "new" to
allocate space for the closure in heap! That gets around the problem.

Although the interface of boost looks very pleasant and all the memory
management are hidden under the hood, the fact that "new" has to be
used for what should have been a vanilla thing makes me feel sad.

In my specific case, I don't need all the rich features such as
bindXXX, all I need is to pass a member function for a hook callback.
And calling a "new" for every closure where I don't have to is a bit
of a overkill to me. I don't quite like to pay that price.

My final question about "why pointer to member function at all?" came
from this thought:

What if, let's just say "what if", there's no "PTM" at all, MyClass::f
simply yields a function pointer of type "int (*)(MyClass*)"?

Isn't that simpler, faster and has better compatibility with the
already-existing function pointer? And, more importantly, does it
work?

The "D&E" book justifies PTM as:

"... This only worked with a liberal sprinkling of explicit casts that
never ought to have worked in the first place. It also relied on the
assumption that a member function is passed its object pointer as the
first argument in the way Cfront implements it"

My arguments are:
1. It can be type safe to make T::*f a function pointer of
"int(*)(T*)", if the language wants to do so. Since I can create the
wrapper function manually, there's no reason the compiler cannot
implicitly create it.

2. Making "MyClass::f" a pointer of type "int(*)(T*)" does NOT rely on
an implementation where the "this pointer" is passed as the first
argument.
 
Evidence? Well, look at the wrapper function again.

Whatever the implementation is, you can pass it as the first param,
the second, or weirdly enough - from a global variable, the function
pointer "MyClass::f" simply points to a function from which you can
eventually invoke the real underlying member function.

There's no promise made that this function must have the same address
of the real "member function". It may be the same address of the real
function, may be an address of a proxy function, all up to the
implementation.

3. Even if we do want a PTM where we can enjoy the favorable syntax
"p->ptm(...)", the implementation of PTM can still be such function
pointer.



Relevant Pages

  • Re: Why doesnt Ruby have pointers?
    ... You cannot do anything complicate with C++ unless you use pointer ... Without closure or nested function, if you have a variable and you want ... In ruby the ruby design will change to using closure ... I don't know much about Boost, but it seems that they enabled ...
    (comp.lang.ruby)
  • Re: Function Pointer Query
    ... Note that pointer to member function is incompatible with regular ... needs a callback, you are sadly out of luck. ... void EnumWindows; ...
    (microsoft.public.vc.language)
  • Re: c[++] pointer question
    ... A pointer is a variable that contains a memory address. ... The above are member variables. ... A constructor is a special member function that is meant to initialize ... In modern C++ the initialization is better done via an initializer list, ...
    (comp.lang.cpp)
  • Re: Basic question regarding checkboxes
    ... It appears that your real problem is not understanding that the above call is to a C++ member function. ... Your error message shows you are not calling the MFC version of CheckDlgButton but attempting to call the API version. ... The MFC version is a member function of the dialog and it "knows" the HWND of the dialog. ... If you are making this call in some code module that is not part of the dialog then first you have to call that module, passing it the 'this' pointer from the dialog object. ...
    (microsoft.public.vc.mfc)
  • Re: A C++ Whishlist
    ... > You invoke undefined behaviour and the compiler is free to do as it ... > calls a member function via a NULL pointer. ... > means that it doesn't invoke undefined behaviour, ... > undefined behaviour until you invoke a member function via a NULL ...
    (comp.lang.cpp)