using BaseType = General<typename BaseHelper<Types... >::BaseType>
Зачем нам нужно ::BaseType
в конце?
General<typename BaseHelper<Types... >
и General<typename BaseHelper<Types... >::BaseType
- это разные типы;с помощью ::BaseType
вы выбираете BaseType
, определенный через using
внутри General<typename BaseHelper<Types... >
Какой тип BaseType
будет содержаться в OurClass
, если мы создадим его с OurClass<int,float,Test>
?
Вы получите, что BaseType
определяется как General<General<General<GenBase>>>
.
Я постараюсь шаг за шагом показать вам, как вы получаете этот тип.
У вас есть OurClass<int,float,Test>
, поэтому Types...
равно int, float, Test
, поэтому
// 1: Types... is int, float, Test
using BaseType = typename BaseHelper<int, float, Test>::BaseType;
Следующий шаг: BaseType
в BaseHelper<int, float, Test>
(выбран общий шаблон; Type
равно int
и Types...
- float, Test
) определяется как
// 2: Types... is float, Test
using BaseType = General<typename BaseHelper<float, Test>::BaseType>;
Следующий шаг: BaseType
в BaseHelper<float, Test>
(выбран общий шаблон; Type
- float
и Types...
- Test
) определяется как
// 3: Types... is Test
using BaseType = General<typename BaseHelper<Test>::BaseType>;
Следующий шаг: BaseType
in BaseHelper<Test>
(частичная специализация BaseHelper<Type>
, с Test
в качестве Type
, выбрано) определяется как
// 4
using BaseType = General<GenBase>;
Следующий шаг: подставим General<GenBase>
в 3, поэтому
// 3: BaseHelper<Test>::BaseType> is General<GenBase>
using BaseType = General<General<GenBase>>;
Следующий шаг: подставим General<General<GenBase>>
в 2, поэтому
// 2: BaseHelper<float, Test>::BaseType is General<General<GenBase>>
using BaseType = General<General<General<GenBase>>>;
Последний шаг:подставляем General<General<General<GenBase>>>
в 1,
// 1: BaseHelper<int, float, Test>::BaseType is General<General<General<GenBase>>>
using BaseType = General<General<General<GenBase>>>;
Вывод: OurClass<int,float,Test>::BaseType
есть General<General<General<GenBase>>>
.