代码之家  ›  专栏  ›  技术社区  ›  WrathOfFlame

解压缩函数调用的参数数组

  •  7
  • WrathOfFlame  · 技术社区  · 6 年前

    是否可以将一个函数及其参数列表传递给另一个函数并稍后从内部调用它?

    void testA(int, float, char* ) {}
    void testB(int, float, double ) {} 
    void testC(MyClass, float, double ) {} 
    
    template <class T>
    void applyA(void(*foo)(void*), std::initializer_list<T> args)
    {
        foo(/*unpack args somehow*/);
    }
    
    template <class T>
    void applyB(void(*foo)(void*), std::initializer_list<T> args)
    {
        MyClass cls;
        foo(cls, /*unpack the rest of args*/);
    }
    
    int main()
    {
        applyA(testA, {5, 0.5f, "abc"});
        applyA(testB, {5, 0.5f, 1.5});
        applyB(testC, {0.5f, 1.5});
    }
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   Mihayl    6 年前

    您可以只转发参数,而不使用数组,或者使用元组,如 std::apply() .

    #include <vector>
    
    class MyClass {};
    
    void testA(int, float, const char* ) {}
    void testB(int, float, double ) {} 
    void testC(MyClass, float, double ) {} 
    
    template <class T, typename... Args>
    void applyA(T&& foo, Args... args)
    {
        foo(args...);
    }
    
    template <class T, typename... Args>
    void applyB(T&& foo, Args... args)
    {
        MyClass cls;
        foo(cls, args...);
    }
    
    int main()
    {
        applyA(testA, 5, 0.5f, "abc");
        applyA(testB, 5, 0.5f, 1.5);
        applyB(testC, 0.5f, 1.5);
    
        return 0;
    }
    

    示例 std::应用()

    #include <tuple>
    
    ...
    std::apply(testA, std::make_tuple(5, 0.5f, "abc"));
    std::apply(testB, std::make_tuple(5, 0.5f, 1.5));
    std::apply(testC, std::make_tuple(MyClass{}, 0.5f, 1.5));
    

    自制apply()示例

    在以下人员的帮助下 "unpacking" a tuple to call a matching function pointer 所以问题是 answer .

    template<int ...>
    struct seq { };
    
    template<int N, int ...S>
    struct gens : gens<N-1, N-1, S...> { };
    
    template<int ...S>
    struct gens<0, S...> {
      typedef seq<S...> type;
    };
    
    
    template<typename F, typename Tuple, int... S>
    void my_apply_impl(F&& func, Tuple&& params, seq<S...> ) {
        func(std::get<S>(std::forward<Tuple>(params)) ...);
    }
    
    template<typename F, typename Tuple>
    void my_apply(F&& func, Tuple&& params) {
        my_apply_impl(std::forward<F>(func), std::forward<Tuple>(params), typename gens<std::tuple_size<Tuple>::value>::type() );
    }
    
    ...
    my_apply(testA, std::make_tuple(5, 0.5f, "abc"));
    my_apply(testB, std::make_tuple(5, 0.5f, 1.5));
    my_apply(testC, std::make_tuple(MyClass{}, 0.5f, 1.5));
    

    Demo

        2
  •  0
  •   Alex Zaharov    6 年前

    在上一页中。answer函数必须更新为使用std::decay,这样它也可以接受常量元组(以下更新部分):

    template<typename F, typename Tuple>
    void my_apply(F&& func, Tuple&& params)
    {
        tuples::my_apply_impl(std::forward<F>(func), std::forward<Tuple>(params), typename tuples::gens<std::tuple_size<typename std::decay<Tuple>::type>::value>::type());
    }