在运行时用C ++编写几个类的类

时间:2017-07-30 16:59:11

标签: c++ class templates inheritance

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

X_Y_Z

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

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

Z可以有20多种不同的东西,所有这些都有不同的参数,可以用不同的方式解释。为这20多种类型创建一个类也很简单;因为它们只是stringintbool s。

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

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

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

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

需要注意的是,我需要在解析完成后迭代这些组合事件,作为第二次排序。

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

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

1 个答案:

答案 0 :(得分:0)

如果基于多态的解决方案是可行的,您可以使用双重调度技术来实现这一点 它遵循一个最小的工作示例来说明它是如何工作的:

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*个实例中提取感兴趣的参数。
无论如何,这可以用作开始基于双重调度设计自己的解决方案的一个点。