我有两个有方法的类:
void ClassA::myFunction(void (*fn)() = NULL);
void ClassB::run();
和一些代码
ClassA A();
ClassB B();
void runBfn()
{
B.run();
}
void setup()
{
A.myFunction( runBFn ); // works
A.myFunction( [](void){B.run();} ); // works
A.myFunction( B.run ); // not works
}
为什么a.myfunction(b.run);
不能工作? 我能使它不声明单独的函数(匿名或不)吗?
myFunction()
采用指向独立函数的指针,而不是指向类方法的指针。 非捕获lambda可以隐式地转换为函数指针。
您需要:
MyFunction()
重载:class ClassB; class ClassA { public: void myFunction(void (*fn)()); void myFunction(B &b, void (B::*fn)()); }; class ClassB { public: void run(); };
void ClassA::myFunction(void (*fn)()) { fn(); } void ClassA::myFunction(B &b, void (B::*fn)()) { (b.*fn)(); } void ClassB::run() { ... }
ClassA A; ClassB B; void runBfn() { B.run(); } void setup() { A.myFunction( runBFn ); A.myFunction( [](){ B.run(); } ); A.myFunction( B, &ClassB::run ); }
class Runnable { public: virtual void run() = 0; }; class ClassA { public: void myFunction(void (*fn)()); void myFunction(Runnable &r); }; class ClassB : public Runnable { public: void run() override; };
void ClassA::myFunction(void (*fn)()) { fn(); } void ClassA::myFunction(Runnable &r) { r.run(); } void ClassB::run() { ... }
ClassA A; ClassB B; void runBfn() { B.run(); } void setup() { A.myFunction( runBFn ); A.myFunction( [](){ B.run(); } ); A.myFunction( B ); }
#include <functional> class ClassA { public: void myFunction(std::function<void()> fn); }; class ClassB { public: void run(); };
void ClassA::myFunction(std::function<void()> fn) { fn(); } void ClassB::run() { ... }
ClassA A; ClassB B; void runBfn() { B.run(); } void setup() { A.myFunction( runBFn ); A.myFunction( [](){ B.run(); } ); auto fn = std::bind(&ClassB::run, &B); A.myFunction( fn ); }
class ClassA { public: template<typename Callable> void myFunction(Callable fn) { fn(); } }; class ClassB { public: void run(); };
void ClassB::run() { ... }
ClassA A; ClassB B; void runBfn() { B.run(); } void setup() { A.myFunction( runBFn ); A.myFunction( [](){ B.run(); } ); auto fn = std::bind(&ClassB::run, &B); A.myFunction( fn ); }
您需要更改函数签名:
void myFunction2(void (ClassB::*run)(void), ClassB& b){}
然后叫它用:
A.myFunction2( &ClassB::run, B);
生活在天赐之地。
PS。
这些不是对象而是函数:
ClassA A();
ClassB B();
您可以改用以下方式:
ClassA A{};
ClassB B{};
这是因为成员函数签名是void(classb::*)()
但您希望作为参数void(*)()
我建议您使用std::function
:
#include <functional>
#include <iostream>
class ClassB
{
public:
void print(std::string str) {
std::cout << str << std::endl;
}
};
void test_foo(std::function<void(std::string)> foo)
{
foo("Hello");
}
int main (int argc, const char * argv[])
{
//...
ClassB b;
auto print_f = std::bind(&ClassB::print, b, std::placeholders::_1);
test_foo(print_f);
return 0;
}