使用任意参数存储、解析和调用函数 < >我想创建一个C++库,用户可以在其中传递任意三种不同类型的参数组合的回调函数。该库稍后将在接收到一些数据后解析这些数据,并使用适当的参数调用回调

使用任意参数存储、解析和调用函数 < >我想创建一个C++库,用户可以在其中传递任意三种不同类型的参数组合的回调函数。该库稍后将在接收到一些数据后解析这些数据,并使用适当的参数调用回调,c++,C++,例如: class MyLibrary { public: void registerCallback(std::vector<std::string> patterns, UNKNOWN_TYPE callback) { this->patterns = patterns; this->callback = callback; } void parseData() { for(unsigned int n = 0; n < patterns.size

例如:

class MyLibrary
{
public:
void registerCallback(std::vector<std::string> patterns, UNKNOWN_TYPE callback)
{
  this->patterns = patterns;
  this->callback = callback;
}

void parseData()
{
  for(unsigned int n = 0; n < patterns.size(); ++n)
  {
     DATA data = getDataForPattern(p);
     if(typeIdOfCallbackArgument(callback, n) == typeid(std::string))
       addToCallList(data.asString(), n);
     else if(typeIdOfCallbackArgument(callback, n) == typeid(float))
       addToCallList(data.asFloat(), n);
     else if(typeIdOfCallbackArgument(callback, n) == typeid(std::vector<float>)) 
       addToCallList(data.asVector, n);
  }
  callCallbackWithCallList();
}

private:
std::vector<std::string> patterns;
std::function<UNKNOWN_TYPE> callback;
type_info typeIdOfCallbackArgument(n);
template <typename T>
void addToCallList(T arg, unsigned int position)
{
 // do some magic to store arbitrary arguments in a callList
}
void callCallbackWithCallList()
{
 // do some magic to call callback() with the arguments stashed in the callList
}
};

void另一个回调(std::string propertyName、float value、std::vector vec)
{
setPropertyVector(propertyName、value、vec);
}
我的图书馆图书馆;
lib.registerCallback({“aproperty”、“avalue”、“avector”},另一个回调);
在我看来,有三项任务:

  • 调用回调参数时“捕获”回调参数
  • 在解析回调参数时存储这些参数
  • 使用这样的参数调用回调
  • 我认为,通过为
    registerCallback()
    callback
    参数使用
    template
    ,我可以在编译时使用
    typeid
    ,并在运行时通过要求typeid从其输出推断
    registerCallback()
    中的参数类型。 我想我知道如何通过将回调存储为
    void*
    并手动设置寄存器和堆栈以将参数传递给函数来进行函数调用,但我确实希望避免这种情况(我使用的是armv7,FWIW)

    <> P>有什么C++特性可以用安全和优雅的方式来完成吗?< /P> 请注意:

    • 我明确地希望避免使回调函数成为一个C变量函数,以便使用户代码尽可能简单。也就是说:我希望用户代码看起来尽可能类似于上面的代码
    • 以上是一个简化的情况。实际上,我希望允许用户为不同的
      模式注册几个回调(即:添加更多具有不同参数的
      lib.registerCallback()
      行)

    为什么不创建一个虚拟
    operator()
    重载了所有需要的类型的类接口呢?例如,检查如何为
    std::variant
    实施
    std::visit
    。基本上,您的
    数据
    是一个
    std::variant
    ,回调是传递给
    std::visit
    @KamilCuk的类,谢谢,但是我如何使用任意数量的参数调用回调呢?
    void myCallback(std::string propertyName, float value)
    {
      setProperty(propertyName, value);
    }
    
    MyLibrary lib;
    lib.registerCallback({"aproperty", "avalue"}, myCallback);
    
    void anotherCallback(std::string propertyName, float value, std::vector<float> vec)
    {
      setPropertyVector(propertyName, value, vec);
    }
    
    MyLibrary lib;
    lib.registerCallback({"aproperty", "avalue", "avector"}, anotherCallback);