简体   繁体   中英

Call function pointers and member functions

I want to create a class which can take both normal function pointers but also member functions. Adding ot that it should take any return type and any type and amount of parameters. I've successfully created what i want by using std::async like this:

    template<class... _Args>
    std::result_of_t<_Fn&&(_Args&&...)> operator()(_Args&&... _Ax) {
        mutex.lock();

        //some extra stuff here

        auto task = std::async(std::launch::deferred, _function_data, std::forward<_Args>(_Ax)...);
        task.wait();

        //some more extra stuff here

        mutex.unlock();
        return task.get();
    }

usage:

    Wrapper<decltype(&TestFunction)> function(&TestFunction); //int TestFunction(int test_parameter)
    Wrapper<decltype(&MyClass::Test)> class_function(&MyClass::Test); //void MyClass::Test()
    class_function(&myClass);
    int test = function(10);

However this solution is obviously not optimal. How would i go about calling any type of function without having to use std::async?

std::invoke was indeed the answer to my question although it needed a wrapper class to support calls to functions with return type 'void'. Here's the invoke wrapper i'm using and it's usage:

template<class t>
class invoke {
public:
    template<class c, class... Args>
    invoke(c&& f, Args&&... arg)
    {
        return_value = std::invoke(f, std::forward<Args>(arg)...);
    }
    t get() { return return_value; }
private:
    t return_value;
};
template<>
class invoke<void> {
public:
    template<class c, class... Args>
    invoke(c&& f, Args&&... arg)
    {
        std::invoke(f, std::forward<Args>(arg)...);
    }
    void get() { return; }
};
template<class... _Args, class return_type = std::result_of_t<_Fn && (_Args&&...)>>
return_type operator()(_Args&&... _Ax) {
    mutex.lock();

    auto return_value = invoke<return_type>(_function_data, std::forward<_Args>(_Ax)...);

    mutex.unlock();
    return return_value.get();
}

This is needed since you cannot store a variable of type 'void' but you can return a function with return type of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM