我是C ++的新手,我不确定我是否不知道如何做到这一点,或者我的方法是否完全错误。
我有一个处理阶段的管道:每个阶段获取某个维度的数据,转换它(可能会改变该维度),然后调用该数据的下一个阶段。这些维度在编译时是已知的并且实现为模板参数。方法setNext
用于定义以下阶段。
template<unsigned int dimIn, unsigned int dimOut>
class Stage {
void process(Data<dimIn> dataIn) {
Data<dimOut> processed = // do something
mNextStage.process(processed)
}
void setNext(Data<dimOut>) {
// store pointer to next stage
}
}
这可以按预期工作。为了分组几个阶段并简化它们的构造,我想创建一个可以传递不同阶段的Pipeline对象。问题是,阶段的输入/输出维度不相等,所以我不确定如何做到这一点:
template<unsigned int firstDimIn, unsigned int firstDimOut>
class Pipeline {
void addStage(Stage<?,?> stage) {
// template parameters of stage are unknown
}
}
Pipeline也是一个模板,它的参数保存第一阶段的输入维度和最后一阶段的输出维度。
使用示例:
Stage<6,5> s1;
Stage<5,4> s2;
Stage<4,2> s3;
Pipeline<6,2> pipe;
pipe.addStage(s1);
pipe.addStage(s2);
pipe.addStage(s3);
不是使用.addStage()
逐步构建管道,而是使用初始化列表:
Pipeline<6,2> pipe = {s1, s2, s3};
但我在那里遇到同样的问题。
答案 0 :(得分:4)
您可以创建代理并在每add
后返回一个新类型。这可以利用维度的编译时检查。
template<int NBeg, int NEnd> struct Stage {};
template<int N, int Saved>
struct PipelineBuilder {
template<int M>
PipelineBuilder<M, Saved>
AddStage(Stage<N, M>) { return {}; }
void done() {
static_assert(Saved == N, "Incompatible dim");
}
};
template<int NIn, int NOut>
struct Pipeline {
PipelineBuilder<NIn, NOut> GetBuilder() { return {}; }
};
int main() {
Stage<6,5> s1;
Stage<5,4> s2;
Stage<4,3> s3;
Pipeline<6, 2> p;
p
.GetBuilder()
.AddStage(s1)
.AddStage(s2)
.AddStage(s3)
.done()
;
}