In my quest to better understand templates and meta-programming in C++ I'm reading this article, but my understanding of the code snippets quickly diminishes, e.g.:
template<class A, template<class...> class B> struct mp_rename_impl;
template<template<class...> class A, class... T, template<class...> class B>
    struct mp_rename_impl<A<T...>, B>
{
    using type = B<T...>;
};
template<class A, template<class...> class B>
    using mp_rename = typename mp_rename_impl<A, B>::type;
The code is used like:
mp_rename<std::pair<int, float>, std::tuple>        // -> std::tuple<int, float>
mp_rename<mp_list<int, float>, std::pair>           // -> std::pair<int, float>
mp_rename<std::shared_ptr<int>, std::unique_ptr>    // -> std::unique_ptr<int>
Can someone please explain the code like I'm five? I do have a general and basic understanding of non-templated C++.
What I don't get is:
Why is mp_rename_impl forward declared with two type parameters (class A, template<class...> class B), then it's defined and specialized at the same time[*] with three (template<class...> class A, class... T, template<class...> class B) and respectively two(A<T...>, B) type parameters?
I understand that it aliases (using type = B<T...>;) the type to be B<T...> instead of A<T...>, but I don't really get how it is done.
Also why is A a template template parameter only in the specialization?
[*] most certainly I got something wrong here
 
     
     
    