Как работает этот шаблон с использованием? - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть этот фрагмент кода, и я пытаюсь понять, как он работает:

#include <iostream>

class GenBase
{
public:
    void BaseClass()
    {
        std::cout << " BaseClass " << std::endl;
    }
};

template <class Base>
class General: public Base
{
    public:
        void PrintGeneral()
        {
            std::cout << " General " << std::endl;
        }
};

template <typename... Types>
struct BaseHelper;

template <typename Type, typename... Types>
struct BaseHelper< Type, Types...>
{
    using BaseType = General<typename BaseHelper<Types... >::BaseType>;
};

template <typename Type>
struct BaseHelper<Type>
{
    using BaseType = General<GenBase>;
};

template <typename... Types>
class OurClass: public BaseHelper<Types...>::BaseType
{
public:
     void print_smth()
     {
        BaseType::PrintGeneral();
     }

private:
     using BaseType = typename BaseHelper<Types...>::BaseType;
};

class Test
{
  public:
      void foo();
};
  1. using BaseType = General<typename BaseHelper<Types... >::BaseType>

    Зачем нам нужно ::BaseType вend?

  2. Какой тип будет BaseType содержать в OurClass, если мы создадим его с помощью OurClass<int,float,Test>?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

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>>>.

0 голосов
/ 12 декабря 2018
  1. General<typename BaseHelper<Types... >::BaseType доступ к типу using BaseType = General<GenBase>, который имеет доступ к функции void BaseClass().

  2. Использование этого конструктора вызовет BaseHelper <Type, Types...>Таким образом, вы получите BaseHelper с Type = int и Types = float, Test, что даст тип General с Types = float, Test.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...