【发布时间】:2021-09-10 19:11:46
【问题描述】:
我正在尝试实现一个指向成员函数包装器的指针,其中返回类型和参数类型已知,但成员函数的类类型未知。这是针对资源受限(无堆分配/c++ 标准库)微处理器的 C++ 项目。
下面的代码似乎可以工作(你可以运行它HERE),它满足了我们的一般要求,但它使用了 reinterpret_cast hackery。
//can't use any c++ std libs or heap allocation
#include <cstdio>
template<typename Ret,typename... Args>
struct member_cb
{
template<typename T>
void set_cb(T *obj_,Ret (T::*func)(Args...))
{
obj = reinterpret_cast<member_cb*>(obj_);
cb = reinterpret_cast<Ret (member_cb::*)(Args...)>(func);
}
Ret operator()(Args... num)
{
return (obj->*cb)(num...);
}
member_cb* obj;
Ret (member_cb::*cb)(Args...);
};
struct Bar{
void someFunc(int n2){
printf("someFunc called with parameter: %d\n",n2);
}
};
int main()
{
//class type of Bar is not known at wrapper creation
member_cb<void,int> foo;
Bar bar;
foo.set_cb(&bar, &Bar::someFunc);
foo(42);
}
我想在没有 reinterpret_cast 的情况下执行此操作。我相信有一个使用由 set_cb() 函数创建的 lambda 的解决方案,如下所示:
template<typename Ret,typename... Args>
struct member_cb
{
template<typename T>
void set_cb(T *obj_,Ret (T::*func)(Args...))
{
cb_func = [=](Args...num)
{
(obj_->*func)(num...);
};
}
Ret operator()(Args... args)
{
return cb_func(args...);
}
Ret (*cb_func)(Args...);
}
上面的代码不会编译(你可以试试HERE)。问题是像 cb_func 这样的常规函数指针只能指向没有捕获的 lambda,而 lambda 必须捕获 obj_ 和 func 参数。任何有关使这项工作的建议将不胜感激。
【问题讨论】:
-
有一个问题:在 C++ 中,指向成员的类型不能保证都具有相同的大小。它们确实不同,至少在涉及多重继承时是这样。这意味着,任何解决方案都会有其缺点,可能是:编译器依赖性、堆分配、臃肿的
member_cb、臃肿的文本段(大量的蹦床)等等。
标签: c++ embedded function-pointers microprocessors