Variadic Templates C++. Непонятный код
Учу вариативные шаблоны. Напал на хабре на статью: Tuples, unpacking and more. В статье содержится "набросанная на коленке простейшая реализация" кортежа.
1: template<typename... Args>
2: struct tuple;
3:
4: template<typename Head, typename... Tail>
5: struct tuple<Head, Tail...> : tuple<Tail...>
6: {
7: tuple(Head h, Tail... tail)
8: : tuple<Tail...>(tail...), head_(h)
9: {}
10:
11: typedef tuple<Tail...> base_type;
12: base_type& base = static_cast<base_type&>(*this);
13: Head head_;
14: };
15:
16: template<>
17: struct tuple<>
18: {};
23: tuple<int, double, int> t(12, 2.34, 89);
24: std::cout << t.head_ << " " << t.base.head_ << " " << t.base.base.head_ << std::endl;
Как работает наследование и рекурсия, в том числе при инстанцировании шаблонов, я понимаю (мне так казалось до). Но для меня в этом примере загадкой являются строки номер 4 и 5. Если это частичная специализация, то откуда синтаксис наследования? Если это наследование, то как возможны одинаковые идентификаторы?
Объясните, пожалуйста, что тут происходит
*** UPDATE ***
Благодарность господину user7860670 за помощь!
Оказывается, одновременно можно и специализировать шаблон класса, и при этом наследоваться от специализированного шаблона с тем же идентификатором. Пример от user7860670:
template<typename T>
struct tuple
{ };
// частичная специализация + наследование
template<typename T>
struct tuple<T &> : tuple<T *>
{ };
// полная специализация + наследование
template< >
struct tuple<double> : tuple<int>
{ };
А если проделывать это с parameter pack'ом, то благодаря самой его сути всеядности относительно количества принимаемых параметров, можно получить не только код из вопроса, но что-то такое (чего, по всей видимости, нельзя было бы сделать без вариативных шаблонов):
template<typename T, typename ... S>
struct tuple
{ };
// без parameter pack'а потребовалось бы указывать тип при наследовании
template<typename ... S>
struct tuple<int, S ...> : tuple<S ...>
{ };