Skip to main content
gamedev.net
🔒 Locked

Taking a reference to a function pointer?

Started by Gage64 Jul 1, 2008 at 12:31 AM 3 replies 3.2k views
Original Post
Gage64
Gage64
Say I have this function:
void func() {}
If I do this:
void (*f)() = func;
It works, but if I do this:
void (*&f)() = func;
It gives me this error: 'initializing' : cannot convert from 'void (__cdecl *)(void)' to 'void (__cdecl *&)(void)' Does this mean that it's impossible to take a reference to a function pointer? If so, why not? Thanks in advance. EDIT: Looks like it's possible after all:
void (*f)() = func;
void (*&f2)() = f;
Don't know why I didn't think of this sooner. [smile] BTW, the same thing happens when trying to take a pointer to a pointer to a function. It works with the indirection above, but not without it, although in this case I think it's because placing & next to a function's name does nothing, i.e., the following are identical:
void (*f)() = func;
void (*f2)() = &func
So now my question is, is it possible to take a reference to a function pointer in one line of code (i.e., without the indirection)?
Gage64
Gage64
EDIT: Looks like fpsgamer deleted his post for some reason. His suggestion was to do this:

void (&f)() = func;


End of edit.

Hmm, I didn't know you can omit the * like that, although if I use a typedef, then I can't use it:

typedef void (*FuncPtr)();FuncPtr &f = func;    // Same error


But again, this works:

FuncPtr f = func;FuncPtr &f2 = f;


Anyway, this doesn't actually solve my problem, so I guess I'll post what I really want to do.

I want to create a sort of functor that can be used with both free functions and function objects (I think it can also be extended to work with member functions, but I don't need this right now).

So I did this:

template <class R>class FunctorBase {public:	virtual R* operator()(const std::string &path) = 0;	virtual ~FunctorBase() {}};template <class T, class R>class Functor : public FunctorBase<R> {public:	Functor(T f):f(f) {}	R* operator()(const std::string &path) {		return f(path);	}private:	T f;};int* func(const std::string &path) {	cout << "func: " << path << endl;	return NULL;}typedef int* (*FuncPtr)(const std::string&);class FuncObj {public:	char* operator()(const std::string &path) {		cout << "FuncObj: " << path << endl;		return NULL;	}};int main(){	Functor<FuncPtr, int> f1(func);	f1("Test 1");	Functor<FuncObj, char> f2((FuncObj()));    // ZOMG!!! Can you see it? :)	f2("Test 2");}


This code does what I want, but the problem is with Functor's constructor - it takes it's argument by value. With function pointers, this doesn't matter because only a pointer is being passed, but with function objects I want to avoid the copy.

The obvious solution to me was to pass the argument by reference, but then I got the error I mentioned earlier.

Is there some way to solve this?

BTW, I know that boost probably has something to do all this for me, but I still want to figure this out.

[Edited by - Gage64 on July 1, 2008 3:17:00 AM]
m3mb3rsh1p
m3mb3rsh1p
Hi. I couldn't fully understand the issues with declaration so I decided to use your functor goals for some, hopefully relevant, practice.

#include <iostream>template< typename callable, typename return_type >return_type redirect(const callable& func, const std::string& nameof_callable,	const return_type& param, const std::string& path){	std::cout << nameof_callable << "(" << param << ")"	<< "; path = " << path << "\n\n";	return func(param);}int plus3(int i) { return i + 3; }class multiplier{public:	multiplier(int f): factor(f) {}	int operator()(int f) const { return factor * f; }private:	int factor;};int main(){	std::cout << redirect(plus3, "plus3", 3, "/home/") << "\n\n";	std::cout << redirect(multiplier(2), "multiplier(2)::operator()", 2, "/home/\n\n");		return 0;}


It was difficult (impossible?) to get "redirect" to call a member function. I ended up grappling with std::mem_fun and how to pass parameters to it (using bind?)
Enigma
Enigma
// a functionvoid func(){}// an objectint i;// a pointer to a functionvoid (*fp)() = func;// a pointer to an objectint * p = &i// a reference to a functionvoid (&fr)() = func;// a reference to an objectint & r = i;// error - fpr is a reference to pointer, func decays to an rvalue of// type void (*)(), rvalues cannot be bound to references to non-const// void (*&fpr)() = func;// error - pr is a reference to a pointer, &i is an rvalue of type int *,// rvalues cannot be bound to references to non-const// int * & pr = &i// a reference to a const pointervoid (* const & fpcr)() = func;// a reference to a const objectint * const & pcr = &i
Hopefully you can now see the solution to your problem.

Σnigma
Gage64
Gage64
Quote:
Original post by Enigma
...
Hopefully you can now see the solution to your problem.


Thank you for a detailed reply, as always.

Passing the argument by const reference indeed solves the problem. I don't know why I didn't try this myself, although even if I did, I wouldn't understand why it would have worked. With your explanation I do... sort of. [smile]

Quote:
Original post by m3mb3rsh1p
It was difficult (impossible?) to get "redirect" to call a member function.


This functor is only supposed to work with functions and function objects. Like I said, I think it can be extended to work with member functions, but I didn't need that so I didn't bother trying.

Anyway, after I wrote some more code I had stumbled upon some other problems, and although I can fix them, I don't feel like messing with this anymore. I will just use boost::function instead.

BTW, I'm a little disappointed that no one has commented on the ZOMG line, but oh well...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.