C + + parses the required parameters according to the passed function pointer

C + + can obtain the required parameter types according to the function pointer passed in, and then obtain the required parameters according to the parameter source. Here I use tuple as a demonstration. However, as long as the actual parameters can be obtained according to the sequence number or order, similar methods can be used:

First, an auxiliary function is given:

/*
* Get nth type
*/


template <typename... Cases>
struct select
{

};

template <typename T, typename... Cases>
struct select<T, Cases...> : public select<Cases...>
{
    using ThisType = T;
    using Base = select<Cases...>;
};

 

The following is the actual implementation function:

#include <functional>
#include "vs-help.h"

class TupleFunc
{
public:
    TupleFunc() { }

    // The actual construction process of function
    template <typename Ret, typename... Args, typename ParamsSource>
    void makeFuncAndParams(Ret(*func)(Args...), ParamsSource& paramSource)
    {
        makeFuncAndParamsImpl<0>(func, select<Args...>(), paramSource);
    }

    // Actual call
    void invoke() 
    {
        m_func();
    }

private:
    // Actual call initialization
    template <size_t idx, typename Func, typename Select, typename ParamsSource, typename... Params>
    void makeFuncAndParamsImpl(Func&& func, Select, ParamsSource& paramSource, Params&&...args)
    {
        typename Select::ThisType param = std::get<idx>(paramSource);
        makeFuncAndParamsImpl<idx + 1>(func, Select::Base(), paramSource, std::forward<Params>(args)..., std::move(param));
    }
        
    // End call
    template <size_t idx, typename Func, typename ParamSource, typename... Params>
    void makeFuncAndParamsImpl(Func&& func, select<>, ParamSource& paramSource, Params&&... args)
    {
        m_func = [func, args...]() { func(args...); };
    }

private:
    std::function<void()> m_func;
};

Here are the test cases:

void print(int x, std::string y)
{
    std::cout << "x: " << x << std::endl;
    std::cout << "y: " << y << std::endl;
}


int main()
{
    std::tuple<int, std::string, std::string> p = { 12, "job", "China" };

    TupleFunc func;
    func.makeFuncAndParams(&print, p);
    func.invoke();

    return 0;
}

Through the use of lambda expression, we can easily build a function we need when we call, and the existence of templates can make us dynamic when building a lambda expression, so that in some cases, we can more flexibly build various processing functions map, etc. The above is just a simple demonstration. In specific scenarios, some modifications are needed.

Keywords: Go Lambda

Added by GBahle on Thu, 19 Mar 2020 20:48:21 +0200