C++ 成员函数的多个非静态回调

问题描述

我发现使用链接答案/下面的代码效果很好,但在我的用例中存在问题。它有效地为非静态成员函数创建了一个“静态包装器”,作为回调传递。

#include <stdio.h>
#include <functional>

template <typename T>
struct Callback;
template <typename Ret,typename... Params>
struct Callback<Ret(Params...)> {
   template <typename... Args>
   static Ret callback(Args... args) {
      return func(args...);
   }
   static std::function<Ret(Params...)> func;
};
template <typename Ret,typename... Params>
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;

所以我在头文件中有那个位,然后各种类都有如下代码。问题是,当试图在同一范围内定义两个这样的回调时,第二个会覆盖第一个

typedef int (*callback_t)(int*,int*);

Callback<int(int*,int*)>::func = std::bind(&myClass::myMethod1,this,std::placeholders::_1,std::placeholders::_2);
callback_t func1 = static_cast<callback_t>(Callback<int(int*,int*)>::callback);      
register_task1_with_library(func1);

Callback<int(int*,int*)>::func = std::bind(&myClass::myMethod2,std::placeholders::_2);
callback_t func2 = static_cast<callback_t>(Callback<int(int*,int*)>::callback);      
register_task2_with_library(func2);

一个注册的回调被重定向到第二个。 为此类内容创建第二个“静态包装器”的最小更改是什么? 似乎必须复制头文件的全部内容,用 Callback2 之类的内容替换 Callback,以便有第二个“静态包装器”可用。

还有一个更简单的例子,它显示了同样的问题:

#include <iostream>
#include "callback.hpp"
void print1(std::string msg)
{
    std::cout << "print1:\t" << msg << std::endl;
}
void print2(std::string msg)
{
    std::cout << "print2:\t\t" << msg << std::endl;
}
int main(int argc,char ** argv)
{
    typedef void (*callback_t)(std::string);
    Callback<void(std::string)>::func = std::bind(print1,std::placeholders::_1);
    callback_t func1 = static_cast<callback_t>(Callback<void(std::string)>::callback);

    Callback<void(std::string)>::func = std::bind(print2,std::placeholders::_1);
    callback_t func2 = static_cast<callback_t>(Callback<void(std::string)>::callback);

    func1("howdy");
    func2("partner");
    return 0;
}

相关项目:https://stackoverflow.com/a/29817048/2725742Using a c++ class member function as a c callback function,thread safe version

修改后的模板是我在评论讨论后得出的结果,我的测试表明它在我的用例中很好。添加的“标签”参数有助于保持每个项目的唯一性。

template <typename T,int tag = 0>
struct Callback;
template <typename Ret,typename... Params,int tag>
struct Callback<Ret(Params...),tag> {
   template <typename... Args>
   static Ret callback(Args... args) {
      return func(args...);
   }
   int m_tag = tag;
   static std::function<Ret(Params...)> func;
};
template <typename Ret,int tag>
std::function<Ret(Params...)> Callback<Ret(Params...),tag>::func;

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)