Reputation: 1145
Is there a way in C++ to make an "untyed" function pointer ? For example:
// pointer to global function
void foo( void (*fptr)() );
// pointer to member
void foo( void (Bar::*fptr)() );
Is there a way I can remove the class on which the member is ? So that I could do something like this:
void foo( void ("any type"::*fptr)(), "same type as for the pointer" &instance );
And then, in foo, I would like to store that pointer in a list, so that I can iterator over the list and call the function/member pointed to, regardless of what class it belongs to. Of course I'd need a list of instances on which to call the function.
Thx.
Upvotes: 0
Views: 1321
Reputation:
You can't have a pointer like that, but you could have a collection of boost::any
, and put heterogeneous pointers (or any kind of functors) into it.
Upvotes: 0
Reputation: 146920
You can use a template.
template<typename T> void foo( void(T::*)(), T&) { ... }
However, people prefer to go for the function object approach. You can do this dynamically or statically.
void foo(std::function<void()> func) {
// std::bind is used to make this out of a member function
}
template<typename T> void foo(T t = T()) {
t(); // This is the best approach.
}
Edit: Some examples.
void foo(std::function<void()> func) {
std::cout << "In example one ";
func();
}
template<typename T> void foo(T t = T()) {
std::cout << "In example two ";
t();
}
class some_class {
public:
void func() { std::cout << "in ur function!\n"; }
};
int main(void)
{
some_class* ptr = NULL;
struct tempfunctor {
tempfunctor(some_class* newptr)
: ptr(newptr) {}
some_class* ptr;
void operator()() { return ptr->func(); }
};
foo(tempfunctor(ptr)); // Calls example two
foo(std::function<void()>(tempfunctor(ptr))); // Calls example one
foo(std::function<void()>(std::bind(&some_class::func, ptr)); // I'm not that familiar with bind, it looks something similar to this.
std::cin.get();
}
This is the idiom called the function object idiom, used heavily in STL and other high-quality libraries. The compile-time template is cleaner but the std::function can be bound at runtime.
Edit @ OP: I didn't quite see your list requirement in there. A std::function<void()>
is your best choice here.
Upvotes: 7
Reputation: 145269
The following seems to work fine with g++ and MSVC:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
void foo( boost::function<int()> f )
{
cout << "f() = " << f() << endl;
}
template< class Type >
void foo( int (Type::*f)() const, Type const& o )
{
foo( boost::bind( f, boost::ref( o ) ) );
}
int func1() { return 1; }
struct S { int func2() const { return 2; } };
int main()
{
foo( func1 );
foo( &S::func2, S() );
}
Disclaimer: I seldom use the Boost stuff and I just typed the above without bothering to check the docs, so possibly it could be expressed more cleanly.
Also note that C++0x standard library offers the same functionality.
Cheers & hth.,
Upvotes: 3
Reputation: 38825
Have a look at Fast Delegates: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
This is an easy drop-in library that allows you to delegate pretty much anything and at a very high speed.
Upvotes: 1
Reputation:
template <typename T>
void foo( void (T::*fptr)(), T& instance)
{
// ...
}
I'm not going to play expert here, but I think this will work, if not I would like to know why.
Upvotes: 0
Reputation: 9378
You can't do that, and you shouldn't do that even if you could, because it is against the spirit of the language. Create a base class with "fptr" as a pure virtual member, and inherit all your classes from that class.
Upvotes: -1
Reputation: 9278
Can you use functors in your list?
http://en.wikipedia.org/wiki/Function_object
Upvotes: 1
Reputation: 41384
No. The bound class is an intrinsic part of the member function pointer type.
You can, however, use a member function pointer to a common baseclass, or a template.
Upvotes: 1