Search code examples
c++templates

How to simplify variable parameter template functions?


Recently, I came up with an idea when learning to call function pointers. I used template variable parameters to construct template functions so that I can call function pointers

#include<functional>
#include<Windows.h>
template<class T, class ...Args>
decltype(auto) ExecuteFunc(LPVOID f, Args&& ...args) {
    if (f != nullptr) {
        return std::function<T>((T*)f)(std::forward<Args>(args)...);
    }
}
int main(){
ExecuteFunc<int(HWND, char*, char*, int)>(&MessageBoxA, (HWND)NULL, (char*)"Text", (char*)"caption", MB_OK);
return 0;
}

Although this code runs well, it seems a bit too long picture Is there a way to shorten the code?

I hope the code can be simplified to call.

ExecuteFunc<int>(&MessageBoxA, (HWND)NULL, (char*)"Text", (char*)"caption", MB_OK);

If you have some interesting ideas, please express them freely.

Supplementary description. Some of the answers misunderstood my question and changed the type of the argument, which apparently std::invoke doesn't do yet. Argument one is passed in as a function pointer address, not the name of an already exported function Example 2.

LPVOID FunAddr=&MessageBoxA;
int ret=ExecuteFunc<int>(FunAddr, (HWND)NULL, (char*) "Text", (char*) "caption", MB_OK);

int ret=ExecuteFunc<int> means that the return value of the function is of type int FunAddr is the address of a function where you can't directly give the symbolic name of the function the rest of the function's parameters

Also I know that FunAddr doesn't have any available type information, but the parameters given can extract this type information and splice it to T(int,int)

template<class T,class . .Args>
T ExecuteFunc(LPVOID f, Args&&... .args) {

}

Solution

  • Thank you to all our friends for your support and comments. Your enthusiastic comments have provided me with constructive help At the moment I have accepted a more simple answer, which meets my needs very well.

    The code and examples are as follows

    template<class T,class F, class ...Args>
    inline decltype(auto) ExecuteFunc(F f, Args&&...args) {
        return reinterpret_cast<T(*)(Args...)>(f)(args...);
    }
    
    

    Example

    #include<Windows.h>
    #include<iostream>
    template<class T, class F, class ...Args>
    inline decltype(auto) ExecuteFunc(F f, Args&&...args) {
        return reinterpret_cast<T(*)(Args...)>(f)(args...);
    }
    int Add(int a, int b) {
        return a + b;
    }
    
    int main(){
        //1.
        LPVOID funcptr = &Add;
        std::cout << ExecuteFunc<int>(funcptr, 1, 2) << std::endl;
        //2.
        std::cout << ExecuteFunc<int>(Add, 3, 5) << std::endl;
        //3.
        ExecuteFunc<int>(MessageBoxA,(HWND)NULL, (char*)"Text", (char*)"caption", MB_OK);
        return 0;
    }
    

    Output