你可以将派生类对象作为函数参数来代替基类对象

时间:2018-02-25 00:26:56

标签: c++ c++11 c++14 template-meta-programming

我正在尝试使用表达式模板添加矩阵,对于此任务,我有基类:Exp

template<typename subtype>
class Exp{
public:
  inline const subtype& self(void) const{
    return *static_cast<const subtype*>(this);
  }

};

派生类:矩阵

template<typename T,unsigned rows_,unsigned cols_ >
class matrix : public Exp<matrix<T,rows_,cols_>>{
   //some members
};

和另一个派生类:addExp

template<typename T, typename Op1 , typename Op2>
class addExp: public Exp< addExp<T,Op1,Op2> >{
  const Op1& op1;
  const Op2& op2;

public:
  addExp(const Op1& a, const Op2& b): op1(a), op2(b){}

  T& operator()(const std::size_t i,const std::size_t j) const{ 
    return op1(i,j) + op2(i,j); 
  }
}; 

我现在正尝试在addExp上执行运算符重载以添加矩阵。

template<typename T,typename Lhs, typename Rhs>
inline addExp<T,Lhs, Rhs>
operator+(const Exp<Lhs> &lhs, const Exp<Rhs> &rhs) {
  return addExp<T,Lhs, Rhs>(lhs.self(), rhs.self());
}

稍后在我的代码中我尝试将两个矩阵对象(应该使用Exp作为基类)作为函数参数,但是我得到一个错误:

prog.cpp: In function ‘int main()’:
prog.cpp:76:25: error: no match for ‘operator+’ (operand types are ‘matrix<int, 3u, 3u>’ and ‘matrix<int, 3u, 3u>’)
  matrix<int,3,3> m3 = m1+m2;
                       ~~^~~
prog.cpp:69:1: note: candidate: template<class T, class Lhs, class Rhs> addExp<T, Lhs, Rhs> operator+(const Exp<Lhs>&, const Exp<Rhs>&)
 operator+(const Exp<Lhs> &lhs, const Exp<Rhs> &rhs) {
 ^~~~~~~~
prog.cpp:69:1: note:   template argument deduction/substitution failed:
prog.cpp:76:26: note:   couldn't deduce template parameter ‘T’
  matrix<int,3,3> m3 = m1+m2;  

我在哪里出错了,如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您需要以某种方式将T的信息转移到operator+。它可以通过多种方式完成,最好的方法在很大程度上取决于您的用例。

这是一种方法。

template<typename T,unsigned rows_,unsigned cols_ >
class matrix : public Exp<matrix<T,rows_,cols_>>{
    using type = T;
    //some members
};

template<typename Lhs, typename Rhs, typename T = typename Lhs::type>
inline addExp<T,Lhs, Rhs>
operator+(const Exp<Lhs> &lhs, const Exp<Rhs> &rhs) {
  return addExp<T,Lhs, Rhs>(lhs.self(), rhs.self());
}