Advertisement

Funky function pointers (and references and plain functions)

Started by July 15, 2004 09:41 AM
5 comments, last by GameDev.net 20 years, 4 months ago
I was just messing around with some function pointers after re-reading Effective STL and it's comments on C++'s most vexing parse. In that chapter Scott Meyers mentions how in C++ as well as function pointers you can have references to functions too:
void (&function)();
And also that you can omit the pointer operator in function pointers passed as arguments - it is implicit:
void function1(void (function2)());
So I was messing around with typedef's of functions to see what could be done. One of the nifty but pointless things I found was that you can declare a function pointer by doing:
typedef void (function)();
function* functionPointer;
But imagine my surprise when I discovered that both GCC and Borland allow you to use this function typedef for forward declarations:
typedef void (function)();
function someFunction;
void anotherFunction()
{
	someFunction();
}
void someFunction()
{
}
And then my complete bafflement to discover that Borland (but not GCC) can actually compile the following:
#include <iostream>

typedef int (function)(int value);

function square
{
	return value * value;
}

function absoluteValue
{
	if (value < 0)
	{
		return -value;
	}
	return value;
}

int main()
{
	std::cout << square(5) << '\n';
	function* functionPointer = absoluteValue;
	std::cout << functionPointer(-7) << '\n';
}
Now is that funky or what! Now the big question does anybody have a copy of the standard or a sufficiently advanced knowledge of the language to tell me if any of this is standards compliant? I'm guessing that using a function typedef to declare a function pointer:
typedef void (function)();
function* functionPointer;
is standards compliant and the other stuff isn't, but I'd love to know for sure. Enigma
Hmm... I just read about this in Sutter's Mill, in the July
2004 issue of C/C++ Users Journal.

"Function types are a little-known but widely supported and
useful feature in C++".

Interesting read.

I don't know the exact reference to the Standard, but I assume
it is a compliant feature.
神はサイコロを振らない!
Advertisement
what is the point in doing this? im still relatively a beginner to C/C++ so my understanding of function pointers is nill. What benefit do you get from typedef'ing funtions?
C_C(Enter witty/insightful/profound remark here...)
That's sweet stuff - good detective work :) I don't know how much is standards compliant unfortunately, but it is none-the-less cool.

Regarding Borland, I've become somewhat addicted to the "__closure" keyword that it allows (I'm using C++ Builder 6). It allows something that seems to be an obvious omission in standard C++: a function pointer to point to the member function of a DERIVED class (from the one that it is declared as). This is necessary to facilitate the "event" system of C++ Builder, but I also find that it comes in handy in other cases, and it has a much simpler syntax than standard member function pointers.

Anyways function points are fun stuff... I'm also interested in the answer to this question.
I use function pointers all the time in my windows library:
// define a structure to pass message parameterstypedef struct tag_MessageData{    // values passed to the handler    WPARAM w_param;    LPARAM l_param;    // values returned from the handler    int return_code;    bool use_default;} MessageData;// define the pointer to a message handlertypedef void (*FnMessageHandler) (MessageData &data);// define the map of messages and message handlerstypedef struct tag_Handler{    UINT message_id;    FnMessageHandler handler;} Handler;// define the handlers for a windowHandler handlers [] ={    {WM_CREATE, On_WM_CREATE},    {WM_DESTROY, On_WM_DESTROY},    // and so on};

In my WndProc function, I scan the 'handlers' array and if an entry for a message is found, create the MessageData structure and then call the corresponding function.

Skizz
function square{	return value * value;}function absoluteValue{	if (value < 0)	{		return -value;	}	return value;}


It's interesting, but I fail to see a use for this funkiness that will only cause confusion. It does make C++ look less and less like C++ though (couple this with odd macros and whatnot and you could make someone think they're writing in a scripting language but they're actually writing C++ code).

Regards,
Jeff
Advertisement
ya, I was gonna say... function pointers are nice because if you want to do some kind of event-handling system with event handlers & event listeners... you can use the subscriber design pattern and do something like this:

class eventListener {public:bool receiveEvent(event*);}void eventHandler::subscribe ( eventListener* el, event* e ) {this->getListners(e)->pushback(el);//if e is NULL, then the listener is subsribed to all events}eventHandler::handleEvent(event* e) {for(allListeners) {  if(listener->receiveEvent(e)) {    break;  }}}


This topic is closed to new replies.

Advertisement