gpt4 book ai didi

c++ - 模板化基类还有一个共同的基类指针?

转载 作者:行者123 更新时间:2023-11-30 04:49:22 32 4
gpt4 key购买 nike

我正在尝试构建一个执行图,其中每个节点都可以生成多个不同类型的输出并使用多个不同类型的输入。数据通过队列在节点之间传输。

要连接 2 个节点,一个节点的输入类型必须连接到另一个节点的相同输出类型。例如,尝试连接 int一个节点的输出到 double另一个节点的输入应该产生编译错误。

所有节点都将派生自具有 execute() 的基类从不同的输入类型读取并写入不同的输出类型的方法。目前,我有这样的东西-

struct Node {
virtual void execute() = 0;
};

struct IntegerGeneratorNode: public Node {
void execute() {
while(some_condition_is_not_met) {
// write() will do std::queue<int>::push();
int_out.write(some_rand_integer);
}
}
Output<int> int_out;
};

struct FloatGeneratorNode: public Node {
void execute() {
while(some_condition_is_not_met) {
// write() will do std::queue<float>::push();
float_out.write(some_rand_float);
}
}
Output<float> float_out;
};

struct SinkNode: public Node {
void execute() {
while(some_condition) {
int val = int_inp.read(); // invokes queue<int>::front()+pop()
float f_val = float_inp.read();
// Do something with val and f_val.
}
}
Input<int> int_inp;
Input<float> float_inp;
};

Input<T>是一个模板类,有一个 queue类型 T . Output<T>是一个模板类,它有一个指向 queue 的指针类型 T .要连接 2 个节点,我会做类似的事情-

Node *int_node = IntegerGeneratorNode();
Node *float_node = FloatGeneratorNode();
Node *sink_node = SinkNode();

int_node.int_out.connect(sink_node.int_inp);
float_node.float_out.connect(sink_node.float_inpt);

std::thread int_thread([](Node *node){ node->execute(); }, int_node);
std::thread float_thread([](Node *node){ node->execute(); }, float_node);
std::thread sink_thread([](Node *node){ node->execute(); }, sink_node);

这工作正常,但我有另一个要求 - 对所有 Input<T> 执行一些操作Node的小号在 execute 之前方法被调用 - Input<T>::doSomePreProcessing() .如您所见,命名变量无法扩展。您必须添加 .doSomething在你拥有的所有变量上。我需要某种循环。

一个想法是有一个 tupleInput使用 C++17 类型和迭代元组 std::apply .但我的另一个主要要求是派生类是客户端代码,基类是框架代码。所有预处理都必须从基类开始,以减轻派生类的负担。为此,我需要像这样将元组移动到基类-

template<typename T>
struct Node {
virtual void execute() = 0;
void doExecute {
preprocess(some_tuple);
execute();
}
T inputs() { return input_tuple; }
T input_tuple;
};

template<typename T>
struct SinkNode: public Node<T>{
...
};

// Call site.
SinkNode<std::tuple<int,float>> sink_node;

由于此更改而产生了 2 个副作用

  1. 基类现在是模板化的,我不能再拥有调用 doExecute 所需的公共(public)基类指针。图节点上的方法。

  2. connect很难实现。理想情况下,我正在寻找的是

template<typename T>
void connect(Node* src, Node* dest) {
std::get<T>(src.outputs()).connect(std::get<T>(dest.inputs()));
}

但是自Node*不再可用,我不能这样做。

如何对基类中的输入进行所有处理,同时拥有一个公共(public)基类指针?换句话说,它没有模板化吗?

最佳答案

想到了几种方法:

  1. virtual void execute() = 0 拆分为一个单独的基类,然后从中派生不同的模板化基类。
  2. 应用装饰器模式:只需创建一个包装另一个 Node 类的 Node 类。当调用外部 execute() 时,预处理输入,然后调用内部 execute()
  3. 使用多重继承。一个基类可能提供 execute() 接口(interface),另一个基类可能提供预处理接口(interface)。这与第一个变体类似,只是两个部分不是堆叠在一起,而是在同一层上并排放置。

关于c++ - 模板化基类还有一个共同的基类指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55439334/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com