【问题标题】:C++ self-adding a static-polymorphic class to a constexpr list of subclassesC++ 将静态多态类自动添加到子类的 constexpr 列表中
【发布时间】:2018-05-06 23:08:34
【问题描述】:

我有大量的子类订阅初始化和实体删除等各种事件。

目前我通过这样做来解决这个问题

class A{ static void init(); void kill(ID); }
class B{ static void init(); void kill(ID); }
class C{ static void init(); void kill(ID); }
A::init();
B::init();
C::init();

其中,使用多行编辑器并不难,而且阅读起来也很简单,但是有很多错误的余地,主要是记住将每个新类添加到调用部分,而不是像这样添加自己的类动态多态。

我如何使用静态多态将它变成类似的形式

//interface, with default behavior implementation
class W{ static void init(){...} void kill(ID){...} }

class A : W<A> {}
class B : W<B> { static void init(){...} }

constexpr auto w_classes = magic_classlist(A, B, ...)

w_classes::init();

使用对象方法,制作静态转换对象列表很容易。
但我需要类功能。因此,要制作一个可迭代的类列表,而不需要手动将它们添加到模板中,如果可能的话,最好是通过继承超类。

【问题讨论】:

  • 从历史上看,这是通过工厂设计模式解决的,请参阅stackoverflow.com/questions/5120768/…
  • 以不需要手动添加类的方式重写此代码最终会导致更大、更困难的问题——找出哪些类是自添加的。消除重复的初始化/终止代码很容易——只需保留一个类元组(或其他类型的类型列表)并为每个类调用一个方法。
  • 这里的区别是我想在编译时这样做,没有虚拟

标签: c++ templates variadic-templates static-polymorphism


【解决方案1】:

也许以下对你来说就足够了:

template <typename ... Ts>
class magic_classlist
{
    static void init()
    {
        (Ts::init(), ...); // C++17, but can be done for C++11
    }
};

然后:

constexpr auto w_classes = magic_classlist<A, B, ...>();

w_classes::init();

【讨论】:

  • 我尝试用一​​个宏来做类似的事情,将一个 lambda 应用到一个可变参数列表中,但是可变参数宏的语法过于神秘,所以我决定了这一点。我仍然必须显式初始化静态成员,这很烦人,但我想这只是这种方法的成本。
猜你喜欢
  • 2014-03-09
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-17
相关资源
最近更新 更多