template<typename... T> struct varSzabl{};
To jest deklaracja szablonu struktury z jedną paczką parametrów.
Paczka parametrów jest to parametrem szablonu który akceptuje 0 lub więcej parametrów szablonowych wliczając w to typy, nie typy oraz inne szablony.
template<typename T, typename... Rest>
struct varSzabl<T, Rest...> : varSzabl<Rest...> {
// ...
};
To jest deklaracja specjalizacji szablonu.
Podczas dedukcji parametrów szablonu standard precyzuje że specjalizacje powinny być brane pod uwagę z większym priorytetem, czyli jeżeli są możliwe dopasowania do podstawowego szablonu i specjalizacji szablonu to zostanie wybrana specjalizacja szablonu.
typ varSzabl<T, Rest...> dziedziczy po typie varSzabl<Rest...>. Gdy uruchamiany jest konsturktor danego typu to wcześniej przed wykonaniem jego kodu uruchamiane są wszystkie konsturktor klas bazowych przez co wypisuje 2, 1 a nie 1, 2.
deklarując zmienną w maine
varSzabl<int, double> iD(1., 2.);
następują takie dedukcje
// użyta zostaje specjalizacja
template<T = int, Rest= [double] >
struct varSzabl<int, double> : varSzabl<double> /* <- (1) */ {
// ...
};
// użyta zostaje specjalizacja
template<T = double, Rest = []>
struct varSzabl<double> /* <- (1) */ : varSzabl<> /* <- (2) */ {
// ...
};
// użyta zostaje podstawowa definicja
template<T = []>
struct varSzabl /* <- (2) */ {};
ten kod jest koncepcyjnie równoważny z takim kodem bez szablonów
#include <iostream>
using namespace std;
struct Szbl {};
struct SzblDouble : Szbl {
SzblDouble(double typb) : Szbl(), obTypuBiez(typb) {
std::cout << obTypuBiez << " ";
}
double obTypuBiez;
};
struct SzblIntDouble : SzblDouble {
SzblIntDouble(int typb, double rest) : SzblDouble(rest), obTypuBiez(typb) {
std::cout << obTypuBiez << " ";
}
double obTypuBiez;
};
int main() {
SzblIntDouble szbl(1., 2.);
system("pause");
}
Możesz sobie doczytać o szablonach tutaj, i paczkach parametrów tutaj.
// Edit
Bardzo polecam stronę https://cppinsights.io/ pozwala zobaczyć dokładniej co kompilator robi z kodem. Tutaj masz odnośnik z twoim kodem.