私は (私のより知識のある同僚も) 解決方法 (回避策) を知っている問題に出くわしました。最終的に問題になるのは、仮想テンプレート関数を作成できないことです。私はネットを徹底的に検索し、それに対処するいくつかの方法を見つけましたが、私の場合はどれも当てはまらないようです.
この状況を簡単に説明する方法はわかりませんが、最善を尽くし、それが理にかなっていることを願っています.
問題は、2 つの曲線を処理することです。それぞれの曲線は、同じまたは異なる曲線タイプの 1 つまたは複数のセグメントで構成されています。そこで、相互作用する曲線のテンプレート クラスを使用して、曲線セグメントのインターフェイスを作成することから始めました (たとえば、関数は 2 つの異なる曲線セグメント間の交差と同じタイプです)。
template<class curve> class curve_segment { // some methods here }
ユーザーは、いくつかのタイプの曲線と、相互作用する曲線に応じて適切な関数を実装できます。たとえば、circle
andline
では、両方が両方と対話できます。
class line : public curve_segment<line>, public curve_segment<circle> { //... }
class circle : public curve_segment<line>, public curve_segment<circle> { //... }
それに続いて、cell
2 つの曲線セグメントに依存する class と、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
}
最後に、そのようなセルの 2D グリッド m*n があり、2 つの曲線はcurve_segments
おそらく異なるタイプの m と n で構成され、各セルの 2 つのポインターによって一緒に保持されます。
新しいcurve_segmentが2つの曲線の1つに追加されると、問題が発生し始めます。明らかな解決策は、追加することです
template<class curve> virtual void add_curve_x(curve_segment<curve> seg) =0;
のcell_base
実装がcell
他の曲線の適切なセグメントを抽出し、それに新しいセルを追加できるクラスに。たとえば、curvea
とb
wherea
がグリッドの x 軸を表し、別の曲線セグメントを curve に追加する場合a
、グリッドの右側のほとんどのセルを見つけ、そのような各セルの y 軸で曲線を抽出できます。 、そしてそれと新しく提供されたセグメントから新しいセルが作成され、それが右に追加されます。
作成時に新しく追加されたセグメントのタイプを知る必要があるため、タイプの消去は機能しませんcell
(両方のセグメントのタイプをテンプレート パラメーターとしてcell
クラスに提供する必要があります)。
テンプレートをcell_base
クラスに移動することも機能しません。これは、各cell
割り当て時に next の型を知る必要があることを意味するためcurve_segment
です。
これを回避する方法はありますか?
editadd_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 つのセグメントを持つカーブの 2 つのカーブがあります。classline
は とcurve_segment<line>
同様に実装curve_segment<circle>
する必要があり、 circle も両方を実装する必要があります。次に、別のベジエ曲線セグメントを curve に追加しましょうa
。クラスbezier
は と を実装する必要がcurve_segment<line>
ありcurve_segment<circle>
、line
とcircle
は を実装する必要がありますcurve_segment<bezier>
。
太字の 3 つの中間を作成する方法を見てみましょうcells
。私たちは電話をかけます
add_curve_x<bezier>(new bezier(...));
型のセル オブジェクトcell<circle, circle>
。
引数seg
は新しいbezier
オブジェクト ( にキャストできるcurve_segment<circle>
) になり、それがcurve
タイプであり、segment_y
にキャストする必要がありますcurve_segment<bezier>
。これは、新しく作成されたセルで相互作用している曲線のタイプであるためです。