Variadic Templates - different types of expansion

前端 未结 2 1691
北海茫月
北海茫月 2020-12-30 07:59

Andrei Alexandrescu gave an excellent talk entitled: Variadic Templates are Funadic.

He presents the following 3 expansions which are subltey different:



        
相关标签:
2条回答
  • 2020-12-30 08:37
    #include <iostream>
    #include <memory>
    #include <typeinfo>
    #include <cstdlib>
    #include <cxxabi.h>
    
    template <typename T>
    std::unique_ptr<char, void(*)(void*)>
    type_name()
    {
        return std::unique_ptr<char, void(*)(void*)>
               (
                    __cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr,
                                               nullptr, nullptr),
                    std::free
               );
    }
    
    void display() {}
    
    template <class T>
    void
    display()
    {
        std::cout << type_name<T>().get() << ' ';
    }
    
    template <class T, class T2, class ...Tail>
    void
    display()
    {
        std::cout << type_name<T>().get() << ' ';
        display<T2, Tail...>();
    }
    
    template <class... Ts>
    struct A
    {
        template <class... Us>
            static
            int
            hun(Us... us)
            {
                std::cout << "A<";
                display<Ts...>();
                std::cout << ">::hun(";
                display<Us...>();
                std::cout << ")\n";
                return 0;
            }
    };
    
    template <class ...T>
    void gun(T...) {}
    
    template <class... Ts> void fun( Ts... vs )
    {
        std::cout << "gun( A<Ts...>::hun(vs)...);\n";
        gun( A<Ts...>::hun(vs)...);
        std::cout << "\ngun( A<Ts...>::hun(vs...));\n";
        gun( A<Ts...>::hun(vs...));
        std::cout << "\ngun( A<Ts>::hun(vs)...);\n";
        gun( A<Ts>::hun(vs)...);
    }
    
    int main()
    {
        fun(1, 'a', 2.3);
    }
    

    Output:

    gun( A<Ts...>::hun(vs)...);
    A<int char double >::hun(int )
    A<int char double >::hun(char )
    A<int char double >::hun(double )
    
    gun( A<Ts...>::hun(vs...));
    A<int char double >::hun(int char double )
    
    gun( A<Ts>::hun(vs)...);
    A<int >::hun(int )
    A<char >::hun(char )
    A<double >::hun(double )
    
    0 讨论(0)
  • 2020-12-30 08:52

    Cases 2 and 3 really are very common in any kind of code involving variadic packs.

    template<typename... T>
    void f(T&&... t)
    {
        // Case 2:
        auto t2 = std::tuple<T...>(t...);
    
        // Case 3:
        auto t3 = std::make_tuple(std::forward<T>(t)...);
    }
    

    Looking at my own code, I can't find any surviving example of case 1. I may have used it in the past in some detail namespace for a helper tempate, but I'm not sure. I don't think it's going to be common or even necessary most of the time.

    0 讨论(0)
提交回复
热议问题