我目前正在尝试包装C库(将其GTK命名为培训)。我想看看是否可以将可变参数模板用于回调,因为它们在信号的回调中具有不同的参数计数。我打算使用std::function
和可变参数模板。有点像这样:
template<typename... args> class callback_t { public:
struct cb_data_t
{
std::function<void (args...)> callback;
};
// data contains cb_data
static void callback_from_a_c_function(args... a, void *data)
{
cb_data_t *cbd = (cb_data *)data;
cbd.callback(a...);
}
private:
cb_data_t cb_data;
};
我对此很陌生,但这是否有可能将可变参数传递给std:function
?
答案 0 :(得分:1)
但这是否有可能将可变参数传递给std:function?
我不理解您要获取的内容,但是...鉴于args...
已固定为该类的模板参数,是的:可以。
在静态方法中进行了两次更正:(1)您必须将data
强制转换为cb_data_t
指针(无cb_data
),并且(2)您必须接受计算cbd
是一个指针,因此您必须通过箭头运算符而不是点运算符来调用callback()
static void callback_from_a_c_function(args... a, void *data)
{ // ......................VV
cb_data_t *cbd = (cb_data_t *)data;
cbd->callback(a...);
} // ^^
或者也许更好,您可以直接将最后一个参数作为cb_data_t
指针
static void callback_from_a_c_function(args... a, cb_data_t * cbd)
{ cbd->callback(a...); }
请注意,接收到cd_data_t
指针作为参数,您就没有使用cb_data
成员。
以下是完整的编译示例,简化了示例
#include <iostream>
#include <functional>
template <typename ... args>
struct callback_t
{
struct cb_data_t
{ std::function<void (args...)> callback; };
static void callback_from_a_c_function(args... a, cb_data_t * cbd)
{ cbd->callback(a...); }
};
extern "C"
{
void foo (int, long)
{ std::cout << "foo!" << std::endl; }
}
int main ()
{
callback_t<int, long>::cb_data_t cbd{&foo};
callback_t<int, long>::callback_from_a_c_function(0, 1l, &cbd);
}
但是在我看来,这种解决方案过于复杂。不幸的是,我不明白您想如何使用包装器,因此我不建议您使用更简单的方法。