这种可变参数模板在使用时如何工作?

时间:2018-12-12 16:53:26

标签: c++ c++11 variadic-templates

我有此代码段,并试图了解其工作原理:

#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

  2. 如果我们用BaseType实例化,OurClass将在OurClass<int,float,Test>中包含什么类型?

2 个答案:

答案 0 :(得分:0)

  1. General<typename BaseHelper<Types... >::BaseType访问using BaseType = General<GenBase>类型,该类型可以访问void BaseClass()函数。

  2. 使用该构造函数将调用BaseHelper <Type, Types...>,因此您将获得BaseHelperType = intTypes = float, Test,这将使General类型Types = float, Test

答案 1 :(得分:0)

  

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>(已选择常规模板; Typeint,而Types...float, Test)定义为< / p>

// 2: Types... is float, Test
using BaseType = General<typename BaseHelper<float, Test>::BaseType>;

下一步:将BaseType中的BaseHelper<float, Test>(已选择常规模板; Typefloat,而Types...Test)定义为< / p>

// 3: Types... is Test
using BaseType = General<typename BaseHelper<Test>::BaseType>;

下一步:将BaseType中的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>::BaseTypeGeneral<General<General<GenBase>>>