在不知道模板参数的情况下传递模板

Passing templates without knowing their parameters

本文关键字:情况下 参数 不知道      更新时间:2023-10-16

我是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
}
}

这按预期工作。为了对多个阶段进行分组并简化它们的构造,我想创建一个可以将不同阶段传递到的管道对象。问题是,阶段的输入/输出维度不相等,所以我不确定如何做到这一点:

template<unsigned int firstDimIn, unsigned int firstDimOut>
class Pipeline {
void addStage(Stage<?,?> stage) {
// template parameters of stage are unknown
}
}

管道也是一个模板,其参数保存第一阶段的输入维度和最后阶段的输出维度。

用法示例:

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};

但我在那里遇到了同样的问题。

您可以创建一个代理并在每次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()
;
}
相关文章: