开发者

C++ function pointer

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开发者_C百科 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.


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.


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.,


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.


Can you use functors in your list?

http://en.wikipedia.org/wiki/Function_object


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.


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜