Variadic 模板继承顺序和语法

Variadic template inheritance order and syntax

我正在尝试通过模板实现一个 signal/slot 系统,以了解模板的一些高级用法。我查找了现有的实现并在 https://github.com/skypjack/eventpp 找到了一个。我一直在努力理解它是如何工作的,并且几乎弄明白了,但仍然有些事情我无法理解,也无法在互联网上找到任何东西(不知道要搜索什么)。

以下是我从 github 存储库中获取的代码以及我自己实现的附加代码的可执行最小示例:

//Signal implementation (own code)
template <typename S>
struct Signal
{
  using type = S;
};

struct KeyPressedEvent : Signal<KeyPressedEvent>
{
  KeyPressedEvent(int keyCode) : keyCode_{keyCode} {}
  int keyCode() {return keyCode_;}

  private:
    int keyCode_;
};

struct KeyReleasedEvent : Signal<KeyReleasedEvent>
{
  KeyReleasedEvent(int keyCode) : keyCode_{keyCode} {}
  int keyCode() {return keyCode_;}

  private:
    int keyCode_;
};    

//Signal Bus implementation (github repo code)
template<int S, typename... E>
struct BusBase;

template<int S, typename E, typename... O>
struct BusBase<S, E, O...> : BusBase<S, O...>
{
  BusBase()
  {
    if(std::is_same<E, KeyPressedEvent>::value)
    {
      std::cout << "BusBase<S, E, O...> KeyPressedEvent" << std::endl;
    }
    if(std::is_same<E, KeyReleasedEvent>::value)
    {
      std::cout << "BusBase<S, E, O...> KeyReleasedEvent" << std::endl;
    }
  }

  Signal<E> signal_;
};

template<int S>
struct BusBase<S>
{
  BusBase()
  {
    std::cout << "BusBase<S>" << std::endl;
  }
};

template <typename... E>
struct Bus : BusBase<sizeof...(E), E...>
{
  Bus()
  {
    std::cout << "Bus" << std::endl;
  }
};

int main(int& argc, const char* args[])
{
  Bus<KeyPressedEvent, KeyReleasedEvent> eventBus;

  std::cin.get();
}

这是我在 运行 程序时得到的输出:

BusBase<S>
BusBase<S, E, O...> KeyReleasedEvent
BusBase<S, E, O...> KeyPressedEvent
Bus

我将陈述我从实施中理解的内容。如有不妥请指正

template<int S, typename... E>
struct BusBase;

需要从 Bus

扩展参数包
BusBase<S, E, O...>

为总线中的每个信号实例化

BusBase<S>

参数包完全展开后需要

我的问题:

1.

BusBase<S>

为什么先实例化这个模板?我本来希望它是最后一个(在公共汽车之前)。

2.

template<int S>
struct BusBase<S>

template<int S, typename E, typename... O>
struct BusBase<S, E, O...> : BusBase<S, O...>

为什么参数既在模板声明中又在结构声明中?

感谢您的帮助。

Why is this template instantiated first? I would have expected it to be last (before Bus).

构造函数调用和实例化是不同的东西

Bus<KeyPressedEvent, KeyReleasedEvent> 继承自 BusBase<2, KeyPressedEvent, KeyReleasedEvent> 继承自 BusBase<2, KeyReleasedEvent> 继承自 BusBase<2>

调用顺序来自 (grand-)parents,成员,构造函数块,所以你有输出。

Why are the parameters both in the template declarations and in the struct declarations?

这是 partial template specialization 的语法。

请注意,这里不需要部分特化,可以重写为:

template<int S, typename ... Es>
struct BusBase
{
  BusBase()
  {
     std::cout << "BusBase<S>\n";
     (print<Es>(), ...);

  }

  template <typename T>
  void print() const
  {
      if constexpr (std::is_same<T, KeyPressedEvent>::value) {
          std::cout << "BusBase<S, Es...> KeyPressedEvent" << std::endl;
      } else if constexpr (std::is_same<T, KeyReleasedEvent>::value) {
          std::cout << "BusBase<S, Es...> KeyReleasedEvent" << std::endl;
      }
  }

  std::tuple<Signal<Es>...> signals_;
};