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