Variadic Templates pack expansions

后端 未结 2 1932
遇见更好的自我
遇见更好的自我 2021-02-08 11:42

In Andrei\'s talk on GoingNative 2012 he talks about Variadic Templates, and he explains at one point by way of the example underneath how the parameter pack expansions work. B

相关标签:
2条回答
  • 2021-02-08 11:54

    1.

       gun(A<Ts...>::hun(vs)...)
    => gun(A<T1, T2, …, Tn>::hun(vs)...)
    => gun(A<T1, T2, …, Tn>::hun(v1),
           A<T1, T2, …, Tn>::hun(v2),
           …,
           A<T1, T2, …, Tn>::hun(vm))
    

    2.

       gun(A<Ts...>::hun(vs...))
    => gun(A<T1, T2, …, Tn>::hun(vs...))
    => gun(A<T1, T2, …, Tn>::hun(v1, v2, …, vm))
    

    This should be obvious.

    3.

       gun(A<Ts>::hun(vs)...)
    => gun(A<T1>::hun(v1), A<T2>::hun(v2), …, A<Tn>::hun(vn))
    

    (In this case the program won't compile if the lengths of Ts and vs differ)


    The ... will expand a pattern (which includes any parameter packs) preceding it, meaning that, in foo(Ts, Us, Vs)..., each member of the list Ts, Us, Vs (enumerated in lock step) will be substituted into that pattern, and a comma separated list will be formed:

       foo(Ts, Us, Vs)...
    => foo(T1, U1, V1), foo(T2, U2, V2), …, foo(Tn, Un, Vn)
    

    And if there are nested expansions, the innermost patterns will be expanded first. Therefore, in case 1, the pattern Ts will first be expanded into T1, T2, …, Tn. And then, the pattern preceding the outer ... is A<T1, T2, …, Tn>::fun(vs) — note that Ts has been expanded — so it will be expanded to A<T1, T2, …, Tn>::fun(v1), A<T1, T2, …, Tn>::fun(v2), …, A<T1, T2, …, Tn>::fun(vm) by substituting v1, v2, etc. into vs.

    0 讨论(0)
  • 2021-02-08 12:17

    KennyTM's answer is perfect. I just also like samples. But since his answer is abstract, I didn't feel like adding demos to his answer is the correct thing. So demos for his answer are here. I'm assuming his answer is right, I know nothing myself. (If you upvote this, upvote his too)

    Obviously this is all psudocode just showing the expanded states.

    void foo<void*,int,char,std::string>(nullptr, 32, '7', "BANANA") {
        //gun(A<Ts...>::hun(vs)...);
        gun(A<void*,int,char,std::string>::hun(nullptr)
           ,A<void*,int,char,std::string>::hun(32)
           ,A<void*,int,char,std::string>::hun('7')
           ,A<void*,int,char,std::string>::hun("BANANA")
           );
        //gun(A<Ts...>::hun(vs...));
        gun(A<void*,int,char,std::string>::hun(nullptr, 32, '7', "BANANA");
        //gun(A<Ts>::hun(vs)...);
        gun(A<void*>::hun(nullptr)
           ,A<int>::hun(32),
           ,A<char>::hun('7'),
           ,A<std::string>::hun("BANANA")
           );
    }
    
    0 讨论(0)
提交回复
热议问题