Obtain Argument Index while Unpacking Argument List with Variadic Templates

后端 未结 2 1919
生来不讨喜
生来不讨喜 2020-12-18 11:57

I need to obtain the index of an argument while unpacking and converting argument list. Is there any solution for the following problem:



        
2条回答
  •  一整个雨季
    2020-12-18 12:19

    This is how I would do it. First of all, you will need some machinery to create compile-time sequences of integers:

    using namespace std;
    
    //===========================================================================
    // META-FUNCTIONS FOR CREATING INDEX LISTS
    
    // The structure that encapsulates index lists
    template 
    struct index_list
    {
    };
    
    // Collects internal details for generating index ranges [MIN, MAX)
    namespace detail
    {
        // Declare primary template for index range builder
        template 
        struct range_builder;
    
        // Base step
        template 
        struct range_builder
        {
            typedef index_list type;
        };
    
        // Induction step
        template 
        struct range_builder : public range_builder
        {
        };
    }
    
    // Meta-function that returns a [MIN, MAX) index range
    template
    using index_range = typename detail::range_builder::type;
    
    //===========================================================================
    

    Then, you could use that machinery for realizing the function call, exploiting the power of argument pack expansion:

    #include 
    #include 
    #include 
    
    void test(int a, std::string b, bool c)
    {
        cout << a << "," << b << "," << c << endl ;
    }
    
    namespace detail
    {
        // This is the function that does the real work.
        template
        void call_test(const vector& params, index_list)
        {
            test((*static_cast(params[Is]))...);
        }
    }
    
    // This function just creates the compile-time integer sequence and 
    // forwards to another function that performs the real work.
    // In other words, this is a proxy that hides the complexity of the
    // machinery from the client.
    template 
    void call_test(const vector& params)
    {
        detail::call_test(params, index_range<0, sizeof...(ARG)>());
    }
    
    int main(int argc, char **argv)
    {
        int    a = 1;
        string b = "string";
        bool c   = false;
        vector v(3);
        v[0] = &a;
        v[1] = &b;
        v[2] = &c;
    
        call_test(v);
    }
    

提交回复
热议问题