Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic templates type deduction

I came across this great article: http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html

In the following code :

template<class A, template<class...> class B> struct mp_rename_impl;

template<template<class...> class C, class... T, template<class...> class B>
struct mp_rename_impl<C<T...>, B>
{
    using type = B<T...>;
};

template<class A, template<class...> class B>
using mp_rename = typename mp_rename_impl<A, B>::type;

//...
mp_rename<mp_list<int, float, void*>, std::tuple>; // -> std::tuple<int, float, void*>
                                                   // T... will be deduced as int, float, void*

Why C is deduced as mp_list (instead of mp_list< int, float, void* >) and T... as int, float, void* ?

I think the trick is the template specialization part : struct mp_rename_impl< C < T... >, B>, But I struggle to understand why

like image 779
Stephane Molina Avatar asked Jun 03 '15 11:06

Stephane Molina


1 Answers

with

mp_rename<mp_list<int, float, void*>, std::tuple>;
  • in

    template<class A, template<class...> class B>
    using mp_rename = typename mp_rename_impl<A, B>::type;
    

    A is mp_list<int, float, void*> and B is std::tuple

  • in

     template<class A, template<class...> class B> struct mp_rename_impl;
    

    A is mp_list<int, float, void*> and B is std::tuple in the same way.

  • in the specialization

    template<template<class...> class C, class... Ts, template<class...> class B>
    struct mp_rename_impl<C<Ts...>, B>
    

    (I rename to C to be clearer)
    C is mp_list, Ts... is int, float, void* and B is std::tuple.

like image 121
Jarod42 Avatar answered Oct 31 '22 18:10

Jarod42