传递非静态成员函数作为函数的参数

时间:2017-11-22 09:16:46

标签: c++ c++11

我需要将非静态成员函数传递给参数

class Foo {
    void f() {}
    void caller() {
        //calling of g() happens here using f()
    }
};

Class Goo {
    std::map<int,std::vector<std::function<void()>>>> m;
    void g(int i, std::function<void()> const& h) {
        m[i].push_back(h);
    }
}

我试着打电话 g(f), g(Foo::f), g(std::make_fn(Foo::f), g(std::make_fn(Foo:f, this), g(this.f) 并且还试图将其作为参考(尽管它应该) 我得到的错误是无效使用非静态成员函数。

编辑:我添加了g()

背后的功能

4 个答案:

答案 0 :(得分:2)

您必须解决的问题是this参数对于非静态成员函数是隐式的。这意味着如果你想稍后调用成员函数,你也需要将指针传递给对象。

其中一种方法是使用std::bind(&Foo::f, this)

更新1 您可以使用smart pointersFoo的生命周期与std::bind创建的仿函数的生命周期联系起来。

class Foo : std::enable_shared_from_this<Foo> {
    void f() {}
    void caller() {
        // CAVEAT! shared_from_this() will work iff instance of `Foo` is already owned 
        // by an std::shared_ptr. This means that when you create `Foo`
        // you must do so via std::make_shared<Foo>()
        g(std::bind(&Foo::f, shared_from_this()));
    }
};

这就是如何将Foo的生命周期绑定到通过std::function生成的std::bind的生命周期。

请参阅代码注释中的警告。

更新2 你的仿函数向量不正确。

std::map<int,std::vector<std::function<void()>const&>> m;

必须是

std::map<int,std::vector<std::function<void()>>> m;

(没有const引用)

答案 1 :(得分:0)

您可以使用类型安全的Functor模式将函数作为参数传递,而不是传递函数地址并希望正确的强制转换。

即。为函数 f()声明一个类,并将实现放在 operator()中。您可以使用构造函数来预加载任何类型的函数参数,或使用重载的运算符()的参数。您可以像对象一样传递函数,只要您喜欢就缓存值,并在不再需要时处理任何内存。

答案 2 :(得分:0)

您可以使用lamba来结束成员函数调用:

void g(std::function<void()> const&);

class Foo
{
    void f(void) {}

    void caller(void)
    {
        g
        (
             ::std::function<void (void)>
             {
                  // we need to capture "this" because f is a non-static member function
                  [this](void) -> void
                  {
                      f();
                  }
              }
         );
    }
};

答案 3 :(得分:0)

您可以使用std :: bind

将函数与此绑定
  

g(std :: bind(&amp; Foo :: f,this));

这里有完整的解决方案:

#include <functional>
#include <iostream>
void g(std::function<void()> const& func){
        func();
};
class Foo {
public:
    void f() const{std::cout<<"function f()\n";}
    void caller() const {
        //calling of g() happens here using f()
        g( std::bind(&Foo::f, this) );
    }
};