我有一个带有参数回调的小类
template<typename Ret, typename ...Args>
class Callback
{
public:
typedef Ret (*Ptr)(Args..., void* param);
Ptr m_func;
void* m_param;
void setFunc(void* func) { m_func = (Ptr)func; }
template<typename T>
void setFunc(const T& func) { m_func = (Ptr)func; }
};
“ param”成员是一个空指针,但实际上即使在一个回调的上下文中,它也可能指向不同的结构 所以我可以将setFunc与这样的简单函数一起使用:
void func1(..., ExampleContext* param) { ... }
callback.setFunc(func1);
但是对于不捕获的lambda,我只能将其与严格的void类型一起使用:
callback.setFunc([](..., void* param) { ... });
我可以将lambda转换为其指针,但是我应该编写其typedef并进行强制转换,同时我希望setFunc接受具有任何param类型的lambda,而无需在Callback类之外进行其他转换,我能以某种方式做到这一点吗?谢谢。
答案 0 :(得分:0)
我相信类似的方法应该起作用:
template<typename Ret, typename Param = void, typename ...Args>
class Callback
{
public:
template<typename T = Param>
using Ptr = Ret (*)(Args..., T *param);
Ptr<> m_func;
Param *m_param;
template<typename T = Param>
void setFunc(Ptr<T> func) { m_func = (Ptr<>)func; }
};
工作副本:https://ideone.com/amapu0
但是,您应该知道使用m_func而不将其强制转换回正确的类型是UB。尽管可以按照您的要求进行操作,但是这种类型的转换和对UB的依赖通常表明您的代码需要重构。这可能是x-y problem。为了获得更合适的解决方案,您必须解释为什么要在单个Callback实例中将m_param指向不同的类型。