我偶然发现了一个问题,我(我的任何知识渊博的同事也不知道)知道如何解决(解决问题)。最终的问题是无法创建虚拟模板功能。我已经彻底搜索了网络,找到了几种处理它的方法,但似乎没有一个适用于我的情况。
我不知道如何简短地描述这种情况,但我会尽力而为,希望它有意义。
问题是处理两条曲线,每条曲线都由一个或多个相同或不同曲线类型的段组成。因此,我开始为曲线段创建一个接口,其中包含将与之交互的曲线的模板类(例如,函数与两个不同曲线段之间的交点具有相同的类型):
template<class curve> class curve_segment { // some methods here }
然后,用户可以实现多种类型的曲线,并根据将与之交互的曲线实现适当的功能。例如circle和line,两者都可以交互:
class line : public curve_segment<line>, public curve_segment<circle> { //... }
class circle : public curve_segment<line>, public curve_segment<circle> { //... }
之后,我有一个 class cell,它依赖于两个曲线段,以及一个cell_base封装它的基类:
template<class curve1, class curve2> class cell : public cell_base {
cell_base* up; cell_base* down;
curve_segment<curve1>* segment_x;
curve_segment<curve2>* segment_y;
// some methods that depend on both curves
}
最后,有一个由这些单元组成的二维网格 m*n,其中两条曲线由curve_segments可能不同类型的 m 和 n 组成,并由每个单元中的两个指针保持在一起。
问题开始显示何时将新的 curve_segment 添加到两条曲线之一。显而易见的解决方案是添加
template<class curve> virtual void add_curve_x(curve_segment<curve> seg) =0;
到cell_base类中,其中的实现cell可以提取另一条曲线的适当段,并向其附加一个新单元格。例如,如果曲线a和bwherea表示网格中的 x 轴,并且我们要向曲线添加另一个曲线段a,我们可以找到网格的右侧大多数单元格,提取每个此类单元格的 y 轴上的曲线, 并从中和新提供的段创建一个新单元格,该单元格将附加到它是正确的。
类型擦除不起作用,因为我们需要在cell创建时知道新添加的段的类型(我们需要将两个段的类型作为模板参数提供给cell类)。
将模板移动到cell_base类也行不通,因为这意味着在每次cell分配时我必须知道 next 的类型curve_segment。
有没有解决的办法?
编辑:按照建议,添加add_curve_x方法:
template<class curve1, class curve2>
template<class curve>
cell<curve1, curve>* cell<curve1, curve2>::add_curve_x(curve_segment<curve1>* seg) {
return new cell<curve1, curve>(seg, (curve_segment<curve>*)(this->segment_y));
}
在这种情况下seg必须是类型curve,它必须实现curve_segment<curve1>。segment_y也有执行curve_segment<curve>。
编辑2:解释为什么演员在那里
以非粗体矩形为例。在这种情况下,有两条曲线,a2 段曲线b和 3 段曲线。classline也必须实现curve_segment<line>,curve_segment<circle>而 circle 也必须同时实现。现在让我们将另一个贝塞尔曲线段添加到 curve a。类bezier必须实现curve_segment<line>and curve_segment<circle>,并且lineandcircle必须实现curve_segment<bezier>。
让我们看看我们如何创建粗体三的中间部分cells。我们会打电话
add_curve_x<bezier>(new bezier(...));
在类型的单元格对象上cell<circle, circle>。
参数seg将是一个新bezier对象(可以转换为curve_segment<circle>),这也是curve类型,并且segment_y必须转换为curve_segment<bezier>,因为这是它在新创建的单元格中与之交互的曲线类型。