几何代数C++实现中类型检查的菱形继承问题及优化问询
几何代数C++实现中的类型检查优化问题
现有实现简化示例
template<int p,int q,int r> struct geometric_algebra{ static const int d=p+q+r, e=1<<d; struct multivector { multivector operator|(multivector w){/*...*/} multivector operator&(multivector w){/*...*/} /*...*/ }; template<int g> struct graded_vector : multivector { template<int h> graded_vector<g+h> operator|(graded_vector<h>w) { return {multivector::operator|(w)}; } template<int h> graded_vector<g+h-d> operator&(graded_vector<h>w) { return {multivector::operator&(w)}; } /*...*/ }; };
graded_vector继承自multivector但未重写核心逻辑,其作用是通过类型系统实现严格的维度检查,确保几何操作的合理性:
using pga = geometric_algebra<3,0,1>; using point = pga::graded_vector<1>; using line = pga::graded_vector<2>; using plane = pga::graded_vector<3>; plane a = /*...*/ line l = /*...*/ // 平面与直线的交集是点 point z = a & l; line m = a & l; // 此处应触发编译错误
扩展需求与现有方案的缺陷
在共形几何代数(geometric_algebra<4,1,0>)中,需要额外区分round和flat类型的几何对象,同样希望通过类型检查实现约束。若沿用现有思路新增flat_vector和flat_graded_vector类,会引入两个问题:
- 菱形继承:
flat_graded_vector会通过graded_vector和flat_vector两条路径继承multivector,引发歧义 - 操作重载冗余:由于
graded_vector和flat_vector均重载了操作符,flat_graded_vector需要重新实现所有操作符以整合两者的类型逻辑
问题与已排除方案
是否存在更优的实现方式?
已尝试并排除的方案:
- 组合替代继承:不适用,因为
multivector并非"是否分级"和"是否扁平"两个属性的简单组合 - 混入(mix-ins)模式:不可行,一方面会遇到函数重载签名不匹配的问题;另一方面,
graded<g,flat<mv>>与flat<graded<g, mv>>在概念上等价,但C++类型检查器无法识别这种等价性
最小可复现代码
template<int p,int q,int r> struct geometric_algebra{ static const int d=p+q+r, e=1<<d; struct multivector { int data; //stand-in multivector operator|(multivector w){ return {data | w.data}; //stand-in } multivector operator&(multivector w){ return {data & w.data}; //stand-in } /*...*/ }; template<int g> struct graded_vector : multivector { template<int h> graded_vector<g+h> operator|(graded_vector<h>w) { return {multivector::operator|(w)}; } template<int h> graded_vector<g+h-d> operator&(graded_vector<h>w) { return {multivector::operator&(w)}; } /*...*/ }; }; using pga = geometric_algebra<3,0,1>; using multivector = pga::multivector; using point = pga::graded_vector<1>; using line = pga::graded_vector<2>; using plane = pga::graded_vector<3>; point make_pt(double x,double y,double z){ return {1}; // stand-in } int main() { point u = make_pt(0,0,1); point v = make_pt(0,1,0); point w = make_pt(1,0,0); plane a = u | v | w; point x = make_pt(0,0,0); point y = make_pt(1,1,1); line l = x | y; point z = a & l; }
内容的提问来源于stack exchange,提问作者Jelmer Firet
相关产品推荐
相关产品推荐

