我偶然发现了一个问题,我(我的任何知识渊博的同事也不知道)知道如何解决(解决问题)。最终的问题是无法创建虚拟模板功能。我已经彻底搜索了网络,找到了几种处理它的方法,但似乎没有一个适用于我的情况。
我不知道如何简短地描述这种情况,但我会尽力而为,希望它有意义。
问题是处理两条曲线,每条曲线都由一个或多个相同或不同曲线类型的段组成。因此,我开始为曲线段创建一个接口,其中包含将与之交互的曲线的模板类(例如,函数与两个不同曲线段之间的交点具有相同的类型):
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
和b
wherea
表示网格中的 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:解释为什么演员在那里
以非粗体矩形为例。在这种情况下,有两条曲线,a
2 段曲线b
和 3 段曲线。classline
也必须实现curve_segment<line>
,curve_segment<circle>
而 circle 也必须同时实现。现在让我们将另一个贝塞尔曲线段添加到 curve a
。类bezier
必须实现curve_segment<line>
and curve_segment<circle>
,并且line
andcircle
必须实现curve_segment<bezier>
。
让我们看看我们如何创建粗体三的中间部分cells
。我们会打电话
add_curve_x<bezier>(new bezier(...));
在类型的单元格对象上cell<circle, circle>
。
参数seg
将是一个新bezier
对象(可以转换为curve_segment<circle>
),这也是curve
类型,并且segment_y
必须转换为curve_segment<bezier>
,因为这是它在新创建的单元格中与之交互的曲线类型。