基于基类的方法在生成类中重载操作符

Operators overloading in generated class based on the methods of base class

本文关键字:操作符 重载 方法 于基类 基类      更新时间:2023-10-16

这个问题是关于一些辅助类Traits的实现,用于自动生成一些二阶函数。

例如有两个不同的对象

//some realization of matrix
class MatrixA{
  ...
};
//totally different realization with different
//public members, different constructors etc.
class MatrixB{
  ...
};

和我想在一些高度抽象的代码中使用这两个功能相同的对象(例如在矩阵对角化中)。抽象是指我们不需要知道矩阵对象的具体实现。我们应该定义一些标准运算,如矩阵和,向量乘法等。

为了做到这一点,我使用了一些特性接口
//traits
//template interface for matrix algebra
template<typename MatrixType>
class TemplateAlgebra{
  typedef MatrixType matrix_t;
public:
  virtual matrix_t matrix_add(const matrix_t& m1,
                              const matrix_t& m2) const=0;
};
//template traits class
template<typename MatrixType, typename MatrixAlgebra>
class TemplateTraits{
public:
  typedef MatrixType matrix_t;
  typedef MatrixAlgebra matrix_algebra_t;
};

我定义了一些模板操作(例如这里的求和)。

然后通过定义每个矩阵类型的特定实现

//overriding of concrete matrix algebra for MatrixA type
class AlgebraA:
public TemplateAlgebra<MatrixA>{
public:
  MatrixA matrix_add(const MatrixA& m1,
                     const MatrixA& m2) const override{
    //here we use some operations from MatrixA class
  }
};
//and create a traits for MatrixA
typedef TemplateTraits<MatrixA,AlgebraA> ATraits;

我在一般接口中抽象了每个矩阵类型的单个属性。

所有这些都可以正常工作。

当我试图从一般函数的知识中生成一些额外的函数时,问题就开始了。

//here the place with errors
//the goal of this class is to generate some second-order functions
//from knowledge of some basic functions which defined in traits
template<typename Traits>
class AutoGenerator:
public Traits::matrix_algebra_t{
  typedef typename Traits::matrix_t matrix_t;
  typedef typename Traits::matrix_algebra_t matrix_algebra_t;
public:
  AutoGenerator(){}
  //some member function works perfectly
  void sum(const matrix_t& m1, const matrix_t& m2){
    matrix_algebra_t::matrix_add(m1,m2);//works fine
  }
  //however there is a problem with friend declaration! 
  template<typename T=Traits>
  friend matrix_t operator+(const matrix_t& m1, const matrix_t& m2){
    matrix_algebra_t::matrix_add(m1,m2);//doen't work
  }
};

特别地,您可以看到在生成某些操作符时存在问题。当我编译它时,我有一个错误:error: cannot call member function "...::matrix_add" without object .

我非常清楚为什么会发生这个错误,所以请不要向我解释为什么我试图在没有类对象的情况下调用非静态成员。我只是被这个可能很简单的问题困住了,因为我花了很多时间研究它,但我没有看到一个解决方案。

所以,最后,问题是"如何通过使用一些模板特征类来重载操作符?"特别是+算子。

很抱歉,这是一个很长的解释,我只是想避免一些"愚蠢"的答案在kind off"只是把它添加到特定的矩阵类"。我不想修改特定的类(通过使用外部库的矩阵,我甚至没有访问它)。提前感谢您的帮助!

看来你的代数类没有数据。在这种情况下,创建它的按需实例应该很简单:

template<typename T=Traits>
friend matrix_t operator+(const matrix_t& m1, const matrix_t& m2){
  matrix_algebra_t().matrix_add(m1,m2);
}

区别在于。您的void sum(const matrix_t& m1, const matrix_t& m2)AutoGenerator的成员,它派生自matrix_algebra_t,因此调用matrix_algebra_t::matrix_add(...)有效地从基类调用函数。

您的template<typename T=Traits> friend matrix_t operator+(const matrix_t& m1, const matrix_t& m2)不是AutoGenerator的成员,因此为了能够在其中调用matrix_algebra_t::matrix_add(...), matrix_add()应该是matrix_algebra_t的静态函数。您需要创建一个matrix_algebra_t的对象,并在其上调用函数:

matrix_algebra_t().matrix_add(m1,m2);