如何将“ void(MyClass :: *)(int)”转换为“ void(*)(int)”?

别墅

我正在寻找如何将类成员转换为C风格的回调。

最近,我发现带有特殊绑定hack的答案允许将类成员绑定到C风格的回调:

https://stackoverflow.com/a/39524069/5405443

我有此工作代码将函数MyClass :: f绑定到C函数f:但我想避免将cb_type作为模板参数显式传递给c_bind函数。在提供的示例中,CB的类型为void(*)(int),Func模板参数的类型为void(MyClass :: *)(int)

template<typename CB, typename Func, typename... Params>
CB* c_bind(std::_Bind<Func(Params...)> function) {
    return Callback<typename ActualType<CB>::type, __COUNTER__, Func>::getCallback(function);
}

typedef void (cb_type)(int);

class MyClass {
public:
    void f(int x) {
        std::cout << "Hello from MyClass::f(int), value: " << x << std::endl;
    }
};

int main() {
    MyClass mc;

    auto f = c_bind<cb_type>(std::bind(&MyClass::f, mc, std::placeholders::_1));
    //                ^ how to avoid explicit callback type declaration here?
    f(10);

    return 0;
}

我也发现了这段代码(https://gist.github.com/vikchopde/73b62314379f733e8938f11b246df49c)用于“展开”某种功能。

bool ok = fu::is_unwrappable<decltype(&MyClass::f)>::value; // always false
// fu::unwrap_function<decltype(&MyClass::f)>::type::function_ptr blah; // won't compile

但由于我的未知,它不会起作用。

我的问题是是否有任何变通办法来从具有类成员指针的类型中提取返回类型和args列表,如void(MyClass :: *)(int)和构造C类的void(*)(int)

感谢您的任何帮助!

别墅

首先,我要感谢@Dappur的例子。稍后,使用您的指南,我将使用std :: _ Bind重写我的丑陋绑定接口。我也要感谢@Sam Varshavchik提到那套C ++书籍。我将开始阅读它,使它成为像您一样的C ++大师,以学习“为什么我不能像这样转换它”。但是不幸的是,由于我较差的c ++经验,我现在仍然可以这样做。这是工作代码:

template<class T, unsigned int n, class CallerType>
struct CallbackWrapper;

template<class Ret, class... Params, unsigned int n, class CallerType>
struct CallbackWrapper<Ret(Params...), n, CallerType> {
    static auto get(std::function<Ret(Params...)>&& fn) -> Ret(*)(Params...) {
        func = fn;
        return static_cast<Ret(*)(Params...)>(CallbackWrapper<Ret(Params...), n, CallerType>::callback);
    }

private:
    static std::function<Ret(Params...)> func;

    static Ret callback(Params... args) {
        return func(args...);
    }
};

template<class Ret, class... Params, unsigned int n, class CallerType>
std::function<Ret(Params...)> CallbackWrapper<Ret(Params...), n, CallerType>::func;

template<typename T>
struct lambda_to_stdf {
    using type = void;
};

template<typename Ret, typename Class, typename... Args>
struct lambda_to_stdf<Ret(Class::*)(Args...) const> {
    using type = std::function<Ret(Args...)>;
};

template<class Ret, class Cls, class... Args1, class... Args2>
auto c_bind(std::_Bind<Ret(Cls::*(Cls, Args1...))(Args2...)> function) -> Ret(*)(Args2...) {
    return CallbackWrapper<Ret(Args2...), __COUNTER__, Ret(Cls::*(Cls, Args1...))(Args2...)>::get(std::move(function));
}

template<class Ret, class... Args>
auto c_bind(std::function<Ret(Args...)> function) -> Ret(*)(Args...) {
    return CallbackWrapper<Ret(Args...), __COUNTER__, std::function<Ret(Args...)>>::get(std::move(function));
}

template<class F>
auto c_bind(F function) -> decltype(c_bind((typename lambda_to_stdf<decltype(&F::operator())>::type)(function))) {
    return c_bind((typename lambda_to_stdf<decltype(&F::operator())>::type)(function));
}

用法:

class MyClass {
public:
    void f(int x) {
        std::cout << "Hello from MyClass::f(int), value: " << x << std::endl;
    }
};

int main() {
    MyClass mc;

    auto f = c_bind(std::bind(&MyClass::f, mc, std::placeholders::_1));
    f(10);

    std::function<void(int)> stdf = [](int v) {
        std::cout << "hello from std::function, value: " << v << std::endl;
    };
    auto f2 = c_bind(stdf);
    f2(100);

    auto f3 = c_bind([](int v) -> int {
        std::cout << "hello from lambda, value: " << v << std::endl;
        return 5.0f;
    });
    f3(1000);

    return 0;
}

希望对某人有帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么将指向int的指针转换为void *但将指向函数的指针转换为bool?

来自分类Dev

从不同大小的整数转换为指针(将int作为const void *参数传递)

来自分类Dev

在将void指针强制转换为float * / int *时取消引用

来自分类Dev

将int指针转换为void指针,然后转换为双指针

来自分类Dev

将int转换为void *

来自分类Dev

将void(__ cdecl MyClass :: *)()转换为void *时出错

来自分类Dev

无法将表达式的类型int转换为void swift

来自分类Dev

无法将'void(MyClass :: *)()'转换为'void(*)()

来自分类Dev

将int转换为void * data并获取长度(以字节为单位)

来自分类Dev

无法将类型“ void”隐式转换为“ int”?

来自分类Dev

将int函数转换为void *

来自分类Dev

将void *转换为int并返回

来自分类Dev

在没有警告的情况下将“ void *”转换为int

来自分类Dev

无法将参数'2'的'int(Scheduler :: *)(int,void *)'转换为'int(*)(int,void *)'到'bool irq_InstallISR(int,int(*)(int,void *),无效*)'

来自分类Dev

为什么在C ++中不允许将static_cast从int(*)(int)转换为void *?

来自分类Dev

从(void **)转换为(int *),反之亦然

来自分类Dev

C / C ++将void *强制转换为int(*())(int,...);

来自分类Dev

将void(__ cdecl MyClass :: *)()转换为void *时出错

来自分类Dev

如何将void指针转换为int指针,然后将int指针存储在其中?

来自分类Dev

C ++无法将参数1的'double'转换为'double *'到'void sort(double *,int)'错误

来自分类Dev

C ++在声明为void类型后将int转换为int?

来自分类Dev

将void *转换为int并返回

来自分类Dev

在没有警告的情况下将“ void *”转换为int

来自分类Dev

如何正确地将 vector<int> 转换为 void* 并返回到 vector<int>?

来自分类Dev

将 map<string, int> 转换为 void* 并返回并获取键

来自分类Dev

异步/等待:无法将类型“void”隐式转换为“int[]”

来自分类Dev

无法将“Int”类型的值转换为预期的参数类型“(inout UnsafeMutableBufferPointer<_>, inout Int) throws -> Void”

来自分类Dev

检查 int 是否在范围内时无法将 void 转换为 int

来自分类Dev

如何将 void[] 转换为 U[]

Related 相关文章

  1. 1

    为什么将指向int的指针转换为void *但将指向函数的指针转换为bool?

  2. 2

    从不同大小的整数转换为指针(将int作为const void *参数传递)

  3. 3

    在将void指针强制转换为float * / int *时取消引用

  4. 4

    将int指针转换为void指针,然后转换为双指针

  5. 5

    将int转换为void *

  6. 6

    将void(__ cdecl MyClass :: *)()转换为void *时出错

  7. 7

    无法将表达式的类型int转换为void swift

  8. 8

    无法将'void(MyClass :: *)()'转换为'void(*)()

  9. 9

    将int转换为void * data并获取长度(以字节为单位)

  10. 10

    无法将类型“ void”隐式转换为“ int”?

  11. 11

    将int函数转换为void *

  12. 12

    将void *转换为int并返回

  13. 13

    在没有警告的情况下将“ void *”转换为int

  14. 14

    无法将参数'2'的'int(Scheduler :: *)(int,void *)'转换为'int(*)(int,void *)'到'bool irq_InstallISR(int,int(*)(int,void *),无效*)'

  15. 15

    为什么在C ++中不允许将static_cast从int(*)(int)转换为void *?

  16. 16

    从(void **)转换为(int *),反之亦然

  17. 17

    C / C ++将void *强制转换为int(*())(int,...);

  18. 18

    将void(__ cdecl MyClass :: *)()转换为void *时出错

  19. 19

    如何将void指针转换为int指针,然后将int指针存储在其中?

  20. 20

    C ++无法将参数1的'double'转换为'double *'到'void sort(double *,int)'错误

  21. 21

    C ++在声明为void类型后将int转换为int?

  22. 22

    将void *转换为int并返回

  23. 23

    在没有警告的情况下将“ void *”转换为int

  24. 24

    如何正确地将 vector<int> 转换为 void* 并返回到 vector<int>?

  25. 25

    将 map<string, int> 转换为 void* 并返回并获取键

  26. 26

    异步/等待:无法将类型“void”隐式转换为“int[]”

  27. 27

    无法将“Int”类型的值转换为预期的参数类型“(inout UnsafeMutableBufferPointer<_>, inout Int) throws -> Void”

  28. 28

    检查 int 是否在范围内时无法将 void 转换为 int

  29. 29

    如何将 void[] 转换为 U[]

热门标签

归档