我需要将非静态成员函数传递给参数
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()
答案 0 :(得分:2)
您必须解决的问题是this
参数对于非静态成员函数是隐式的。这意味着如果你想稍后调用成员函数,你也需要将指针传递给对象。
其中一种方法是使用std::bind(&Foo::f, this)
更新1
您可以使用smart pointers将Foo
的生命周期与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) );
}
};