将C ++非捕获Lambda转换为void *

时间:2019-11-30 23:03:29

标签: c++ lambda

我有一个带有参数回调的小类

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类之外进行其他转换,我能以某种方式做到这一点吗?谢谢。

1 个答案:

答案 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指向不同的类型。