代码之家  ›  专栏  ›  技术社区  ›  dotminic

C++函数指针

  •  0
  • dotminic  · 技术社区  · 14 年前

    C++中有没有一种方法可以生成一个“unType”函数指针? 例如:

    // pointer to global function
    void foo( void (*fptr)() );
    
    // pointer to member
    void foo( void (Bar::*fptr)() );
    

    有没有方法可以移除成员所在的类?所以我可以这样做:

    void foo( void ("any type"::*fptr)(), "same type as for the pointer" &instance );
    

    然后,在foo中,我希望将指针存储在一个列表中,这样我就可以遍历该列表并调用所指向的函数/成员,而不管它属于哪个类。当然,我需要一个调用函数的实例列表。

    谢谢。

    8 回复  |  直到 14 年前
        1
  •  7
  •   Puppy    14 年前

    您可以使用模板。

    template<typename T> void foo( void(T::*)(), T&) { ... }
    

    然而,人们更喜欢使用函数对象方法。您可以动态地或静态地这样做。

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

    编辑:一些例子。

    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();
    }
    

    这就是所谓的函数对象习语,在STL和其他高质量的库中大量使用。编译时模板比较干净,但可以在运行时绑定std::函数。

    edit@op:我在那里没有看到您的列表要求。一 std::function<void()> 这是你最好的选择。

        2
  •  3
  •   Cheers and hth. - Alf    14 年前

    以下内容似乎可以与g++和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() );
    }
    

    免责声明:我很少使用Boost的东西,我只是在上面打了个字,不必费心检查文档,所以可能可以更清晰地表达出来。

    还要注意C++0X标准库提供了相同的功能。

    干杯!

        3
  •  1
  •   Crashworks    14 年前

    不是。绑定类是成员函数指针类型的固有部分。

    但是,可以使用指向公共基类或模板的成员函数指针。

        4
  •  1
  •   James    14 年前

    你能在你的列表中使用函数吗?

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

        5
  •  1
  •   Moo-Juice    14 年前

    看看快速学员: http://www.codeproject.com/KB/cpp/FastDelegate.aspx

    这是一个简单的库,它允许您以非常高的速度委托几乎任何事情。

        6
  •  0
  •   Oystein    14 年前
    template <typename T>
    void foo( void (T::*fptr)(), T& instance)
    {
        // ...
    }
    

    我不会在这里扮演专家,但我认为这会奏效,如果不是的话,我想知道为什么。

        7
  •  0
  •   Martin Broadhurst    14 年前

    你不能有那样的指针,但是你可以有一个 boost::any ,并放置异类指针(或任何类型的 仿函数 进入它。

        8
  •  -2
  •   Eugene Smith    14 年前

    你不能这样做,即使你可以也不应该这样做,因为这违背了语言的精神。使用“fptr”创建一个纯虚拟成员的基类,并从该类继承所有类。