Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 虚拟模板功能解决方案_C++_Templates_Virtual Functions - Fatal编程技术网

C++ 虚拟模板功能解决方案

C++ 虚拟模板功能解决方案,c++,templates,virtual-functions,C++,Templates,Virtual Functions,我偶然发现了一个问题,我(也没有任何一个知识更渊博的同事)知道如何解决这个问题。最终的问题是无法创建虚拟模板函数。我彻底搜索了网络,找到了几种处理方法,但似乎没有一种适用于我的情况 简言之,我不知道如何描述这种情况,但我会尽我所能,希望它有意义 问题在于处理两条曲线,每条曲线由一条或多条相同或不同曲线类型的线段组成。因此,我开始为曲线段创建一个接口,它将与一个模板类进行交互(例如,函数与两个不同曲线段之间的交点类型相同): 接下来,我有一个类cell,它依赖于两条曲线段,还有一个基类cell\u

我偶然发现了一个问题,我(也没有任何一个知识更渊博的同事)知道如何解决这个问题。最终的问题是无法创建虚拟模板函数。我彻底搜索了网络,找到了几种处理方法,但似乎没有一种适用于我的情况

简言之,我不知道如何描述这种情况,但我会尽我所能,希望它有意义

问题在于处理两条曲线,每条曲线由一条或多条相同或不同曲线类型的线段组成。因此,我开始为曲线段创建一个接口,它将与一个模板类进行交互(例如,函数与两个不同曲线段之间的交点类型相同):

接下来,我有一个类
cell
,它依赖于两条曲线段,还有一个基类
cell\u 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
}
cell\u base
类,其中
cell
中的实现可以提取另一条曲线的适当段,并向其附加一个新的单元格。例如,如果曲线
a
b
,其中
a
表示网格中的x轴,我们将向曲线
a
添加另一个曲线段,我们可以找到网格中最右侧的单元,提取每个此类单元y轴上的曲线,并从该曲线段和新提供的段生成一个新单元,这将附加到它的权利

类型擦除不起作用,因为我们需要知道在创建
单元格
时新添加的段的类型(我们需要向
单元格
类提供两个段的类型作为模板参数)

将模板移动到
cell\u base
类也不起作用,因为这意味着在每个
cell
分配时,我必须知道下一个
曲线段的类型

有办法解决这个问题吗

编辑: 按照建议,添加
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));
}
在类型为
cell
的cell对象上


参数
seg
将是一个新的
bezier
对象(可以将其转换为
curve\u segment
),这也是
curve
类型,并且
segment\u y
必须转换为
curve\u segment
,因为这是它在新创建的单元格中与之交互的曲线类型。

添加
curve\u segment\u base

class curve_segment_base {
   // for double dispatching here:
  virtual cell_base* add_curve_x(cell_base* cell) = 0;
};

template<class curve> 
class curve_segment : public virtual curve_segment_base { 
     // some specific methods here 
     // for double dispatching here:
     virtual cell_base* add_curve_x(cell_base* cell)
     {
         // this has to be moved to cpp file due to dependency from cell_base
         return cell->add_curve_x(this); // now the correct method from cell is called
     }
};
类曲线\段\基{
//对于此处的双重分派:
虚拟单元_base*添加_曲线_x(单元_base*单元)=0;
};
模板
类curve_segment:公共虚拟曲线_segment_base{
//这里有一些具体的方法
//对于此处的双重分派:
虚拟单元基础*添加曲线(单元基础*单元)
{
//由于与单元库的依赖关系,必须将其移动到cpp文件
return cell->add_curve_x(this);//现在调用单元格中正确的方法
}
};
因此,您可以将此方法作为虚拟方法添加到您的cell_库中

class cell_base {
   virtual cell_base* add_curve_x(curve_segment_base* seg) = 0;

   // methods necessary for double dispatching here:
   virtual cell_base* add_curve_x(curve_segment<line>* seg) = 0;
   virtual cell_base* add_curve_x(curve_segment<circle>* seg) = 0;
   ...
};
类单元\u基{
虚拟单元_-base*添加_曲线_x(曲线_段_-base*seg)=0;
//此处双重调度所需的方法:
虚拟单元_base*添加_curve_x(curve_segment*seg)=0;
虚拟单元_base*添加_curve_x(curve_segment*seg)=0;
...
};
因此,您的方法如下所示,在这里使用双重分派:

template<class curve1, class curve2>
virtual cell_base* cell<curve1, curve2>::add_curve_x(curve_segment_base* seg) {
  return seg->add_curve_x(this);
}
模板
虚拟单元\基本单元*单元::添加\曲线\ x(曲线\段\基本单元*分段){
返回seg->添加曲线(此);
}
您必须为所有细分实施所有真正的实施方法:

template<class curve1, class curve2>
virtual cell_base* cell<curve1, curve2>::add_curve_x(curve_segment<line>* seg) {
  return new cell<curve1, line>(...);
}
template<class curve1, class curve2>
virtual cell_base* cell<curve1, curve2>::add_curve_x(curve_segment<circle>* seg) {
  return new cell<curve1, circle>(...);
}
模板
虚拟单元\基本单元*单元::添加\曲线\ x(曲线\段*分段){
返回新单元格(…);
}
模板
虚拟单元\基本单元*单元::添加\曲线\ x(曲线\段*分段){
返回新单元格(…);
}

不清楚您想做什么。请在
单元格
中显示
添加曲线
的具体实现(想象一下允许使用模板虚拟函数)。仍然不清楚。。。这个演员在那里干什么?可以将任何曲线段强制转换为任何其他曲线段吗?一条曲线可以使用不同的参数实现多个
曲线段
。实现取决于什么样的曲线可能相互影响。在这种情况下,单元格中的曲线与
curve1
curve2
交互,但当我们添加不同类型的曲线段(
curve
)时,
段y
也必须与该曲线段交互。假设有一条曲线由两条直线和一个圆组成,第二条曲线由一条贝塞尔曲线和一条圆和一条直线组成。然后,一切都必须能够与一切交互。最终,我可以强制所有曲线段为同一类型,而不存在此问题,但这将大大降低有用性。如果调用
cell::add\u curve\u x
,演员将尝试将
curve\u segment*
转换为
curve\u segment
。因为这两个类不相关,这将作为
重新解释\u cast
,并产生未定义的行为。谢谢!这是一个很好的解决方案,但这是我试图避免的,因为用户必须实现
add\u curve\ux
,而实际上不需要它。我想我应该选择一种更合适的语言:)
class curve_segment_base {
   // for double dispatching here:
  virtual cell_base* add_curve_x(cell_base* cell) = 0;
};

template<class curve> 
class curve_segment : public virtual curve_segment_base { 
     // some specific methods here 
     // for double dispatching here:
     virtual cell_base* add_curve_x(cell_base* cell)
     {
         // this has to be moved to cpp file due to dependency from cell_base
         return cell->add_curve_x(this); // now the correct method from cell is called
     }
};
class cell_base {
   virtual cell_base* add_curve_x(curve_segment_base* seg) = 0;

   // methods necessary for double dispatching here:
   virtual cell_base* add_curve_x(curve_segment<line>* seg) = 0;
   virtual cell_base* add_curve_x(curve_segment<circle>* seg) = 0;
   ...
};
template<class curve1, class curve2>
virtual cell_base* cell<curve1, curve2>::add_curve_x(curve_segment_base* seg) {
  return seg->add_curve_x(this);
}
template<class curve1, class curve2>
virtual cell_base* cell<curve1, curve2>::add_curve_x(curve_segment<line>* seg) {
  return new cell<curve1, line>(...);
}
template<class curve1, class curve2>
virtual cell_base* cell<curve1, curve2>::add_curve_x(curve_segment<circle>* seg) {
  return new cell<curve1, circle>(...);
}