How to detect the first and the last argument in the variadic templates?

前端 未结 2 849
一整个雨季
一整个雨季 2020-12-14 19:09

How to detect the first and the last argument in the variadic templates?

For the 1st argument it is easy (just compare sizeof...(T) with 0), but is ther

2条回答
  •  离开以前
    2020-12-14 19:21

    Here's another set of code with a convenience function return_type that you could use to access any type at a specific index in a varadic template list ... you could then adapt the call to return_type so that you get the first and the last arguments (i.e., the first argument will be at 0, and the last argument will be at sizeof...(TypeList)):

    template
    struct type_id_struct
    {
        typedef T type;
        T object_instance;
    };
    
    template
    struct reduce {};
    
    template
    struct reduce
    {
        typedef typename reduce::type type;
    };
    
    template
    struct reduce<0, T1, TypeList...>
    {
        typedef T1 type;
    };
    
    //convenience function
    template
    type_id_struct::type> return_type()
    {
            return type_id_struct::type>();
    }
    

    Here's an example of using the convenience function return_type in actual code to determine the Nth template argument in a variadic template:

    int main()
    {
        auto type_returned = return_type<2, int, double, char>();
        std::cout << typeid(type_returned.object_instance).name() << std::endl;
    
        return 0;
    }
    

    In this case, since the int template argument to return_type is 2, you'll get the char type as the output. Any number over 2 will cause an overflow that will create a compile rather than runtime error. As noted, you could adapt it so that it's wrapped inside a function in a structure that will allow you to access the types in the variadic template for that specific structure instance using the sizeof...(TypeList) - 1 applied to an enum. For instance:

    template
    struct an_object
    {
        enum { first = 0, last = (sizeof...(TypeList) - 1) };
    
        template
        auto wrapper() -> decltype(return_type())
        {
                return return_type();
        }
    };
    
    //...more code
    
    int main()
    {
        an_object a;
    
        auto r_type1 = a.wrapper::first>();
        std::cout << typeid(r_type1.object_instance).name() << std::endl;
    
        auto r_type2 = a.wrapper::last>();
        std::cout << typeid(r_type2.object_instance).name() << std::endl;
    
        return 0;
    }
    

提交回复
热议问题