我正在开发一个工作流系统,用于在生产者消费者模型中将任务连接在一起。这个想法是你有一个或多个任务正在生成和消费彼此的数据。我已经实现了任务,现在我试图将它们连接在一起。为了帮助管理这些任务,我创建了一个连接器类,可以将一个或多个生产者任务与一个或多个使用者任务有效连接。
问题是,我正在模仿这些类,以便Task<T, U>
可以定义为某个具有输入类型T(消耗T)和输出类型U(生成U)的任务。
我在下面定义了这个任务:
template <class T, class U>
class Task {
static_assert(std::is_base_of<AbsData, T>::value, "T must derive from AbsData");
static_assert(std::is_base_of<AbsData, U>::value, "U must derive from AbsData");
...
}
接下来将两个任务连接在一起,我使用一个连接器。这在某种程度上代表了两个任务之间的优势。该连接器有两个列表:std::list<Task<AbsData, T> *> *producerTasks;
和std::list<Task<T, AbsData> * consumerTasks;
。我试图做的基本上是忽略一个任务的模板类型之一,并且说我只关心类型T并希望在另一个类型中拥有任何类型。
template <class T>
class Connector {
static_assert(std::is_base_of<AbsData, T>::value, "T must derive from AbsData");
public:
// Is it possible to set up a function so I effectively pass any parent AbsData, but hold onto type T?
void addProducerTask(Task<AbsData, T> *producer) {
this->producerTasks->push_front(producer);
this->producerTaskCount = this->producerTasks->size();
producer->setOutputConnector(this);
}
private:
std::list<Task<AbsData, T> *> *producerTasks;
std::list<Task<T, AbsData> * consumerTasks;
}
主要问题是addProducerTask
是否可以传入一个具有某种类型的AbsData和类型T的任务?
以下是一个例子:
// FFTData inherits AbsData
Connector<FFTData> *connector = new Connector<FFTData>();
Task<FFTData, FFTData> *task = new Task<FFTData, FFTData>(...);
connector->addProducerTask(task);
此示例出现以下编译时错误:Parameter type mismatch: Class 'Task<FFTData, FFTData>' is not compatible with class 'Task<AbsData, FFTData>'
编辑: 我决定重新设计实现以模板化函数。
template <class U>
void addProducerTask(Task<U, T> *producer) {
incrementProducerCount();
producer->setOutputConnector(this);
}
没有必要跟踪连接器所连接的任务,而只需要确保连接器已添加到任务中,因此任务可以从连接器生成/使用数据。尽管能够拥有模板化成员变量会很好,但由于缺少类型擦除,似乎需要进行此返工。
如果我想在中间添加连接器边缘,这也很有效:
template <class Q, class R>
void addEdge(Task<Q, T> *producer, Task<T, R> *consumer) {
producer->setOutputConnector(this);
consumer->setInputConnector(this);
incrementInputTaskCount();
};
答案 0 :(得分:1)
此示例获取以下编译时错误:参数类型 不匹配:Class&#39;
Task<FFTData, FFTData>
&#39;与班级不兼容 &#39;Task<AbsData, FFTData>'
这是因为实际的Task<AbsData, FFTData>
和Task<FFTData, FFTData>
是不相关的类型,无论关系如何
// FFTData inherits AbsData
他们实际的第一个类型参数。
要解决此问题,您可以例如使它们相关(如果它与您设计的其他部分兼容):
#include <type_traits>
#include <list>
struct AbsData {};
struct FFTData : public AbsData{};
template <class T, class U>
class Task : public Task<AbsData, U> {
static_assert(std::is_base_of<AbsData, T>::value,
"T must derive from AbsData");
static_assert(std::is_base_of<AbsData, U>::value,
"U must derive from AbsData");
};
template <class U>
class Task<AbsData, U> {};
template <class T>
class Connector {
static_assert(std::is_base_of<AbsData, T>::value,
"T must derive from AbsData");
public:
// Is it possible to set up a function so I effectively pass
// any parent AbsData, but hold onto type T?
void addProducerTask(Task<AbsData, T> *producer) {
/* this->producerTasks->push_front(producer);
this->producerTaskCount = this->producerTasks->size();
producer->setOutputConnector(this);*/
}
private:
std::list<Task<AbsData, T> *> *producerTasks;
std::list<Task<T, AbsData> *> consumerTasks;
};
int main() {
Connector<FFTData> *connector = new Connector<FFTData>();
Task<FFTData, FFTData> *task = new Task<FFTData, FFTData>();
connector->addProducerTask(task);
return 0;
}
live在Coliru的