C++ C++;:闭包将成员函数作为普通函数指针传递

C++ C++;:闭包将成员函数作为普通函数指针传递,c++,arduino,atmega,C++,Arduino,Atmega,我试图调用外部库的成员函数,该库将函数指针作为参数: Timer::every(unsigned long period, void (*callback)(void)); 但不幸的是,我要传递的参数是一个成员函数: void MyClass::the_method_i_want_to_pass(void); 因为我是在Arduino(AVR)下为ATMega编程,所以对c++11的支持有限。我的第一种方法引发了一个类型错误: void MyClass::the_method_i_want_

我试图调用外部库的成员函数,该库将函数指针作为参数:

Timer::every(unsigned long period, void (*callback)(void));
但不幸的是,我要传递的参数是一个成员函数:

void MyClass::the_method_i_want_to_pass(void);
因为我是在Arduino(AVR)下为ATMega编程,所以对c++11的支持有限。我的第一种方法引发了一个类型错误:

void MyClass::the_method_i_want_to_pass() {...}

MyClass::MyClass() {
    // constructor

    Timer *timer = new Timer();
    timer->every(500, [this](){this->the_method_i_want_to_pass();})
}
编译器输出:

警告:警告:lambda表达式仅适用于-std=c++11或-std=gnu++11[默认启用]

错误:对“Timer::every(int,MyClass::MyClass():::\uu lambda0)”的调用没有匹配的函数

  • 是否有其他/更好的解决方案
  • 关于我目前的方法:(如何)在需要函数指针时传递对lambda的引用
  • 如何确定Arduino/AVR是否支持这些lambda(请参阅“警告”)

  • 你的基本问题是你的
    计时器
    库写得很糟糕:它至少需要
    void(*)(void*),void*

    如果没有pvoid或等效项,则无法传递除执行代码中的地址以外的任何状态来运行该过程。由于一种方法也会重新创建一个
    这个
    指针,所以您运气不好

    现在,如果您的
    MyClass
    实例是一个单例,那么您可以从其他地方获得
    this

    如果做不到这一点,您需要创建自己的全局状态,使您能够从特定回调映射到某个状态。如果您有数量有限的
    MyClass
    Timer
    的其他使用者,您可以有一些固定的函数,并让它们全局存储它们的额外状态

    这完全是胡闹。接下来的情况更糟

    编写一个具有某种全局状态的动态库,以及一个
    void()
    接口。添加回调时,复制该动态库,在运行时修改其全局状态,将其写出为不同名称的库,加载它,并将纯回调函数传递给
    Timer

    或者,在没有库的情况下,通过手动编写机器代码并将页面标记为可执行页面来实现等值


    这些都是糟糕的解决方案。这让我想到了一个好方法:找到一个更好的
    计时器。如果他们搞砸了这么简单的事情,库的其余部分可能也不好。

    你的编译器支持std::mem_fn吗?
    ,它的c++11思想使用了一个类似的端口。这个问题没有意义。这就像说:“我妻子想让我带西红柿回家。我有一盒指甲和一条面包。1.有更好的解决办法吗?2.我怎样才能取悦我的妻子?3.我怎样才能找到一个接受指甲和面包作为西红柿的妻子?”我不明白你的意思@KerrekSB。在我看来,对于第三方图书馆的局限性,这是一个明确的问题。这正是关闭图书馆的目的。。。将作用域/状态封装到函数中。您的建议是什么?谢谢您的回复!我想我会从一个黑客开始,直到我可以用更好的东西取代它。