c++ - 生成带有传递给模板的指针类型签名的函数

标签 c++ metaprogramming c++17

我想创建一个生成器,它为每个指向函数的指针创建一个指针可以指向的 static 函数:

template <auto &PtrToIsrHandler, auto MemberFunction> struct enable_member_isr_handler
{
    using TypeOfCFunPtr = std::remove_reference_t<decltype(PtrToIsrHandler)>;
    using TypeOfCFunPointed = std::remove_pointer_t<TypeOfCFunPtr>;
    using RetType = std::invoke_result_t<TypeOfCFunPointed>;
    static RetType isr_handler(/* dunno what to put here */)
    {
        return /* call MemberFunction here somehow */;
    }

    enable_member_isr_handler()
    {
        PtrToIsrHandler = isr_handler;
    }

};

isr_handler 方法的参数列表中,我尝试使用以下方法放置一个元组:

template <typename T> struct get_parameters;
template <typename Ret, typename... Args> struct get_parameters<Ret(Args...)>
{
    using args_t = std::tuple<Args...>;
};

但我明白了:

error: invalid conversion from void (*)(get_parameters<void()>)}’ to ‘void (*)()’

我怎样才能使 PtrToIsrHandler 成为指向 isr_handler 的有效指针?

最佳答案

正如我在评论中提到的,获取参数列表的一种方法是使用偏特化并转发传入成员函数的类型。同样的方法也可以用于自由函数。

#include <iostream>

template <auto MemberFunction, class MemberFunctionType>
struct handler_impl;

template <auto MemberFunction, class ReturnType, class ClassType, class... Args>
struct handler_impl<MemberFunction, ReturnType(ClassType::*)(Args...)> {
    // here you have access to return-type, class-type and args

    static ReturnType call_on_instance(ClassType& obj, Args... args) {
        return (obj.*MemberFunction)(args...);
    }
};

template <auto MemberFunction>
using handler = handler_impl<MemberFunction, decltype(MemberFunction)>;

struct Foo {
    int print(int x) {
        std::cout << x*x << std::endl;
        return x;
    }
};

int main() {
    Foo f;
    handler<&Foo::print>::call_on_instance(f, 7);
}

这里要记住的一件事是我们没有使用完美转发。最简单的方法就是简单地把call_on_instance做成一个模板函数,这样我们就不需要关心参数和返回值了,让编译器推导就可以了。

另一种选择是使用我上面展示的方法并使用 static_assert 来确保传入的参数列表有效,从而在以错误的方式使用时给出更好的错误消息。

关于c++ - 生成带有传递给模板的指针类型签名的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55033007/

相关文章:

c++ - DLL的Class的方法的使用

c++ - QSerialBus 工作中的内存泄漏

c++ - 显性用户定义的强制转换运算符

java - Java 中可以进行静态元编程吗?

c++ - 重载可变参数模板方法

c++ - 如何声明数组成员变量的getter/setter方法

enums - 枚举如何增强?

c++ - 在编译时找出整数类型的最小值/最大值的位数

c++ - 进程终止,状态为 -1073741571(0 分钟,3 秒)

c++ - 在 [现代] C++ 中通过 N 个变量进行范围/循环