在运行时C++编写多个类的类



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

X_Y_Z

X总是相同的,并且可以解析为具有 8 个成员的类,因为它有 8 个参数。

Y可以是 6 种不同的类型,所有这些类型都有不同数量的参数,可以根据它们Y的类型进行不同的解释。为这 6 种类型中的每一种创建一个类是微不足道的;因为它们只是strings、ints 和bools。

Z可以是 20 多种不同的东西,所有事物都有不同数量的参数,可以有不同的解释。为这 20+ 类型创建一个类也是微不足道的;因为它们只是strings、ints 和bools。

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

template<typename Y, typename Z>
struct Event {
DateTime timestamp;
X base;
Y prefix;
Z suffix;
}

这将允许我们在编译时构造任何可能的事件组合。

问题是日志文件是在运行时解析的,我希望能够在运行时编写这些类,具体取决于我需要的类。此外,我想尽可能避免演员表。

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

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

编辑:我想到的一个解决方案是使用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);
}

因为我不知道细节上真正的问题是什么,我尽力给你一个有意义的例子。我想您可以使用访问者类从已删除的Y*/Z*实例中提取感兴趣的参数。
无论如何,这可以用作开始设计基于双重调度的解决方案的点。

最新更新