gpt4 book ai didi

c++ - 管道类存储具有约束的不同模板

转载 作者:行者123 更新时间:2023-11-28 00:12:33 24 4
gpt4 key购买 nike

我有一个类模板 DataProcessor,它看起来像这样:

struct DataProcessorBase
{
typedef std::shared_ptr<DataProcessorBase> Ptr;
}; // struct DataProcessorBase

template <class _Input, class _Output>
struct DataProcessor : DataProcessorBase
{
typedef _Input Input;
typedef _Output Output;

virtual Output process(const Input * input) = 0;
}; // struct DataProcessor

我想创建一个管道类,它将多个 DataProcessor 实例连接在一起。这意味着处理器 1 的输出必须与处理器 2 的输入匹配,依此类推。类似于以下内容:

template <class _Input, class _Output>
class Pipeline : DataProcessor<_Input, _Output>
{
public:
Output process(const Input * input);
private:
std::vector<DataProcessorBase::Ptr> _processors;
}; // class Pipeline

template <class _Input, class _Output>
_Output Pipeline<_Input, _Output>::process(const _Input * input)
{
// this is where I start guessing...
auto rawPtr = dynamic_cast<DataProcessor<_Input, TYPEOFFIRSTPROCESSORSOUTPUT>*>(_processors[0]);
assert(rawPtr);
for (size_t i = 0; i < _processors.size(); ++i)
{
...
}
}

我可以看出这种实现 Pipeline::process 的方式是不正确的。有人可以指出我正确的方向吗?

最佳答案

解耦输入和输出调用。

数据传入和数据传出应该发生在不同的步骤。然后每个数据消费者都可以知道它需要什么,并为您进行转换(如果出现问题,可能会抛出或标记错误)。

struct processor {
virtual ~processor () {};
virtual bool can_read_from( processor const& ) const = 0;
virtual void read_from( processor& ) = 0;
virtual bool ready_to_sink() const = 0;
virtual bool ready_to_source() const = 0;
};
template<class T>
struct sink {
virtual void operator()( T&& t ) = 0;
virtual ~sink() {}
};
template<class T>
struct source {
virtual T operator()() = 0;
virtual ~source() {}
};
template<class In, class Out, class F>
struct step: processor, sink<In>, source<Out> {
F f;
step( F&& fin ):f(std::move(fin)) {}

step(step&&)=default;
step(step const&)=default;
step& operator=(step&&)=default;
step& operator=(step const&)=default;
step()=default;

std::experimental::optional<Out> data;
virtual void operator()( In&& t ) final override {
data = f(std::move(t));
}
virtual bool ready_to_sink() const {
return !data;
}
virtual Out operator()() final override {
auto tmp = std::move(data);
data = {};
return std::move(*tmp);
}
virtual bool ready_to_source() const final override {
return static_cast<bool>(data);
}
virtual bool can_read_from( processor const& o ) final override {
return dynamic_cast<source<In> const*>(&o);
}
virtual void read_from( processor &o ) final override {
(*this)( dynamic_cast<source<In>&>(o)() );
}
};
template<class In, class Out>
struct pipe {
std::shared_ptr<processor> first_step;
std::vector< std::shared_ptr<processor> > steps;
pipe(std::shared_ptr<processor> first, std::vector<std::shared_ptr<processor>> rest):
first_step(first), steps(std::move(rest))
{}
Out operator()( In&& in ) {
(*dynamic_cast<sink<In>*>(steps.first_step.get()))( std::move(in) );
auto last = first_step;
for (auto step:steps) {
step->read_from( *last );
last = step;
}
return (*dynamic_cast<source<Out>*>(last.get())();
}
};
template<class In, class Out>
struct pipeline:step<In, Out, pipe<In,Out>> {
pipeline( std::shared_pointer<processor> first, std::vector<std::shared_ptr<processor>> steps ):
step<In, Out, pipe<In,Out>>({ first, std::move(steps) })
{}
};

关于c++ - 管道类存储具有约束的不同模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32234662/

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