How do I expand a tuple into variadic template function's arguments?

前端 未结 13 1191
旧时难觅i
旧时难觅i 2020-11-22 07:49

Consider the case of a templated function with variadic template arguments:

template Tret func(const T&... t);
         


        
13条回答
  •  迷失自我
    2020-11-22 08:44

    In C++ there is many ways of expanding/unpacking tuple and apply those tuple elements to a variadic template function. Here is a small helper class which creates index array. It is used a lot in template metaprogramming:

    // ------------- UTILITY---------------
    template struct index_tuple{}; 
    
    template 
    struct make_indexes_impl; 
    
    template 
    struct make_indexes_impl, T, Types...> 
    { 
        typedef typename make_indexes_impl, Types...>::type type; 
    }; 
    
    template 
    struct make_indexes_impl > 
    { 
        typedef index_tuple type; 
    }; 
    
    template 
    struct make_indexes : make_indexes_impl<0, index_tuple<>, Types...> 
    {}; 
    

    Now the code which does the job is not that big:

     // ----------UNPACK TUPLE AND APPLY TO FUNCTION ---------
    #include 
    #include  
    
    using namespace std;
    
    template 
    Ret apply_helper( Ret (*pf)(Args...), index_tuple< Indexes... >, tuple&& tup) 
    { 
        return pf( forward( get(tup))... ); 
    } 
    
    template 
    Ret apply(Ret (*pf)(Args...), const tuple&  tup)
    {
        return apply_helper(pf, typename make_indexes::type(), tuple(tup));
    }
    
    template 
    Ret apply(Ret (*pf)(Args...), tuple&&  tup)
    {
        return apply_helper(pf, typename make_indexes::type(), forward>(tup));
    }
    

    Test is shown bellow:

    // --------------------- TEST ------------------
    void one(int i, double d)
    {
        std::cout << "function one(" << i << ", " << d << ");\n";
    }
    int two(int i)
    {
        std::cout << "function two(" << i << ");\n";
        return i;
    }
    
    int main()
    {
        std::tuple tup(23, 4.5);
        apply(one, tup);
    
        int d = apply(two, std::make_tuple(2));    
    
        return 0;
    }
    

    I'm not big expert in other languages, but I guess that if these languages do not have such functionality in their menu, there is no way to do that. At least with C++ you can, and I think it is not so much complicated...

提交回复
热议问题