C++ 在C+中由几个类组成的类+;运行时

C++ 在C+中由几个类组成的类+;运行时,c++,class,templates,inheritance,C++,Class,Templates,Inheritance,对于我正在开发的解析器,我正在解析事件日志。在日志中,每一行都是一个事件,这使得逐行解析文件变得很容易。记录的事件在开始时有一个字符串标识符,其构造如下: X_Y_Z X始终是相同的,并且可以作为一个包含8个成员的类进行分析,因为它有8个参数 Y可以是6种不同的类型,所有这些类型都有不同数量的参数,这些参数可以根据Y的类型进行不同的解释。为这6种类型中的每一种创建一个类是很简单的;因为它们只是strings、ints和bools Z可以是20多种不同的东西,都有不同数量的参数,可以进行不同的解

对于我正在开发的解析器,我正在解析事件日志。在日志中,每一行都是一个事件,这使得逐行解析文件变得很容易。记录的事件在开始时有一个字符串标识符,其构造如下:

X_Y_Z
X
始终是相同的,并且可以作为一个包含8个成员的类进行分析,因为它有8个参数

Y
可以是6种不同的类型,所有这些类型都有不同数量的参数,这些参数可以根据
Y
的类型进行不同的解释。为这6种类型中的每一种创建一个类是很简单的;因为它们只是
string
s、
int
s和
bool
s

Z
可以是20多种不同的东西,都有不同数量的参数,可以进行不同的解释。为这20多种类型创建一个类也很简单;因为它们只是
string
s、
int
s和
bool
s

因此,事件类可以定义为:

template<typename Y, typename Z>
struct Event {
    DateTime timestamp;
    X base;
    Y prefix;
    Z suffix;
}
模板
结构事件{
日期时间戳;
X基;
Y前缀;
Z后缀;
}
这将允许我们在编译时构造任何可能的事件组合

问题是日志文件在运行时被解析,我希望能够在运行时编写这些类,这取决于我需要什么。此外,我希望尽可能避免使用石膏

需要注意的重要一点是,在解析完成后,作为排序的第二个过程,我需要迭代这些组合事件

实现这一目标最优雅的方式是什么


Edit:我想到的一个解决方案是使用
std::variant
,并将Y和Z作为基于整数的ID存储在事件类中。它可能会工作,但我正在寻找比具有20个参数的
std::variant
更优雅的解决方案。

如果基于多态性的解决方案可行,您可以使用双重分派技术来实现这一点。
下面是一个简单的工作示例,以说明它是如何工作的:

struct X { int i; int j; };

struct Visitor;

struct YBase { virtual void accept(Visitor &) =0; };
struct Y1: YBase { void accept(Visitor &) override; int i; };
struct Y2: YBase { void accept(Visitor &) override; bool b; };

struct ZBase { virtual void accept(Visitor &) = 0; };
struct Z1: ZBase { void accept(Visitor &) override; double d; };
struct Z2: ZBase { void accept(Visitor &) override; char c; };

struct Visitor {
    void visit(Y1 &y1) { y1.i = 0; }
    void visit(Y2 &y2) { y2.b = true; }
    void visit(Z1 &z1) { z1.d = .42; }
    void visit(Z2 &z2) { z2.c = 'c'; }
};

void Y1::accept(Visitor &v) { v.visit(*this); }
void Y2::accept(Visitor &v) { v.visit(*this); }
void Z1::accept(Visitor &v) { v.visit(*this); }
void Z2::accept(Visitor &v) { v.visit(*this); }

struct Event {
    X base;
    YBase *prefix;
    ZBase *suffix;
};

void visit(Event &e) {
    Visitor v;
    e.prefix->accept(v);
    e.suffix->accept(v);
}

int main() {
    Y2 y;
    Z1 z;
    Event e;
    e.prefix = &y;
    e.suffix = &z;
    visit(e);
}
因为我不知道什么是真正的问题在细节上,我尽我所能给你一个有意义的例子。我想您可以使用visitor类从已擦除的
Y*
/
Z*
实例中提取感兴趣的参数。

无论如何,这可以作为开始设计基于双重分派的自己的解决方案的起点。

如果事件是
Y1,Z1
类型而不是
Y6,Z20
类型,则可以在主函数中为类动态分配内存,这取决于您需要采取哪些不同的操作。如果答案是-没什么,您可能只需要存储一组字段。那么,120个组合中的每个组合都需要不同的逻辑吗?不是所有的120个组合都需要不同的逻辑,比如说有大约50个不同的路径可供选择。是否有特定的需要使其成为一个模板(静态多态性)而不是使用继承(动态多态性)?不,动态多态性也是可以接受的。