Jump to content
  • Advertisement
Sign in to follow this  
Gage64

Taking a reference to a function pointer?

This topic is 3644 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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)?

Share this post


Link to post
Share on other sites
Advertisement
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]

Share this post


Link to post
Share on other sites
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?)

Share this post


Link to post
Share on other sites
// a function
void func()
{
}

// an object
int i;

// a pointer to a function
void (*fp)() = func;

// a pointer to an object
int * p = &i;

// a reference to a function
void (&fr)() = func;

// a reference to an object
int & 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 pointer
void (* const & fpcr)() = func;

// a reference to a const object
int * const & pcr = &i;
Hopefully you can now see the solution to your problem.

Σnigma

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!