C++ 为什么在此CRTP基函数调用中添加引用会删除错误?

C++ 为什么在此CRTP基函数调用中添加引用会删除错误?,c++,inheritance,reference,crtp,C++,Inheritance,Reference,Crtp,我最近一直在尝试使用奇怪的循环模板模式来实现各种矩阵类,但遇到了一些我不理解的行为 当我有 template <class T> double& MatrixBase<T>::operator()(int row, int col) { return static_cast<T&>(*this).operator()(row, col); } template double&MatrixBase::operator()(in

我最近一直在尝试使用奇怪的循环模板模式来实现各种矩阵类,但遇到了一些我不理解的行为

当我有

    template <class T> double& MatrixBase<T>::operator()(int row, int col)
{
     return static_cast<T&>(*this).operator()(row, col);
}
template double&MatrixBase::operator()(int行,int列)
{
返回静态_cast(*this).operator()(行,列);
}
我没有错误。如果我有

            template <class T> double& MatrixBase<T>::operator()(int row, int col)
{
    return static_cast<T>(*this).operator()(row, col);
}
template double&MatrixBase::operator()(int行,int列)
{
返回静态_cast(*this).operator()(行,列);
}
我收到以下错误消息:

src/matrices.cpp:15:12: error: no matching conversion for stati
c_cast from 'nav::MatrixBase<nav::Matrix>' to 'nav::Matrix'
    return static_cast<T>(*this).operator()(row, col);
           ^~~~~~~~~~~~~~~~~~~~~
src/matrices.cpp:122:24: note: in instantiation of member funct
ion 'nav::MatrixBase<nav::Matrix>::operator()' requested here
        dm(pos, pos) = operator()(pos, pos);
                       ^
src/matrices.cpp:636:23: note: in instantiation of member funct
ion 'nav::MatrixBase<nav::Matrix>::toDiagonalMatrix' requested here
        *this = thisAsMatrix.toDiagonalMatrix();
                             ^
src/matrices.h:85:7: note: candidate constructor (the implicit
copy constructor) not viable: no known conversion from 'nav::MatrixBase<nav::Mat
rix>' to 'const nav::Matrix' for 1st argument
class Matrix : public MatrixBase<Matrix>
      ^
src/matrices.cpp:199:9: note: candidate constructor not viable:
 requires 0 arguments, but 1 was provided
Matrix::Matrix() : rows_{}, cols_{}, data_{}
        ^
src/matrices.cpp:206:9: note: candidate constructor not viable:
 requires 2 arguments, but 1 was provided
Matrix::Matrix(int num_rows, int num_cols)
src/matrix.cpp:15:12:错误:stati没有匹配的转换
c_从“导航::矩阵库”转换为“导航::矩阵”
返回静态_cast(*this).operator()(行,列);
^~~~~~~~~~~~~~~~~~~~~
src/matrix.cpp:122:24:注意:在成员函数的实例化中
此处请求了“nav::MatrixBase::operator()”离子
dm(pos,pos)=运算符()(pos,pos);
^
src/matrix.cpp:636:23:注意:在成员函数的实例化中
此处请求ion“nav::MatrixBase::toDiagonalMatrix”
*this=thisAsMatrix.toDiagonalMatrix();
^
src/matrix.h:85:7:注:候选构造函数(隐式
复制构造函数)不可行:没有已知的第一个参数从“nav::MatrixBase”到“const nav::Matrix”的转换
类矩阵:公共矩阵库
^
src/matrix.cpp:199:9:注:候选构造函数不可行:
需要0个参数,但提供了1个
矩阵::矩阵():行{},列{},数据{}
^
src/matrix.cpp:206:9:注:候选构造函数不可行:
需要2个参数,但提供了1个
矩阵::矩阵(整数行,整数列)
让我感到特别奇怪的是,我的MatrixBase/Matrix类的其他成员没有T作为引用,但没有抛出任何错误

下面是使用的更多代码:

template <class T> double& MatrixBase<T>::operator()(int row, int col)
{
    return static_cast<T&>(*this).operator()(row, col);
}

template <class T> double MatrixBase<T>::operator()(int row, int col) const
{
    return static_cast<T>(*this).operator()(row, col);
}

template <class T> T& MatrixBase<T>::operator=(double value)
{
    return static_cast<T>(*this).operator=(value);
}

template <class T> T& MatrixBase<T>::operator=(T& a)
{
    return static_cast<T>(*this).operator=(a);
}

// Add another derived Matrix to this derived Matrix
template <class T> T& MatrixBase<T>::operator+=(T& a)
{
    return static_cast<T>(*this).operator+=(a);
}


double& Matrix::operator()(int row, int col)
{
    REQUIRE(row >= 0 && col >= 0, "Error: Indices must be non-negative.");
    REQUIRE(row < rows_ && col < cols_, "Error: Element index outside matrix.");
    return data_[row][col];
}

double Matrix::operator()(int row, int col) const
{
    REQUIRE(row >= 0 && col >= 0, "Error: Indices must be non-negative.");
    REQUIRE(row < rows_ && col < cols_, "Error: Element index outside matrix.");
    return data_[row][col];
}

/*****************************************************************************
 *   Purpose:  Initializes the whole matrix to the specified value.
 ******************************************************************************/
Matrix& Matrix::operator=(double value)
{
    for(int i = 0; i < rows_; i++)
    {
        for(int j = 0; j < cols_; j++)
        {
            data_[i][j] = value;
        }
    }
    return *this;
}

/*****************************************************************************
*   Purpose:  Copies one matrix to another.
******************************************************************************/
Matrix& Matrix::operator=(const Matrix& a)
{
    int iteratedRows = 0;
    while(iteratedRows < a.rows())
    {
        if(this->rows() - 1 < iteratedRows)
        {
            this->data_.push_back(pfstl::VectorN<double, kMaxDimension>());
            this->rows_++; // we added a new row
        }
        int iteratedCols = 0;
        while(iteratedCols < a.cols())
        {
            if(this->cols() - 1 < iteratedCols)
            {
                this->data_[iteratedRows].push_back(a(iteratedRows, iteratedCols));
            }
            else
            {
                this->data_[iteratedRows][iteratedCols] = a(iteratedRows, iteratedCols);
            }
            iteratedCols++;
        }
        iteratedRows++;
    }
    // if a has less rows than this, force this to have the same # of rows as a
    while(a.rows() < this->rows_)
    {
        // In order to make the sizes equal, remove excess rows from this from the back
        this->data_.erase(end(this->data_));
        this->rows_--;
    }
    // Same logic as above for columns
    while(a.cols() < this->cols_)
    {
        for(int i = 0; i < this->rows_; i++)
        {
            this->data_[i].erase(end(this->data_[i]));
        }
        this->cols_--;
    }

    this->rows_ = a.rows();
    this->cols_ = a.cols();

    return *this;
}

// Add another derived Matrix to this derived Matrix
Matrix& Matrix::operator+=(const Matrix& a)
{

    REQUIRE(rows_ == a.rows(), "Error: Matrix addition requires same number of rows.");
    REQUIRE(cols_ == a.cols(), "Error: Matrix addition requires same number of columns.");

    for(int i = 0; i < a.rows(); i++)
    {
        for(int k = 0; k < a.cols(); k++)
        {
            data_[i][k] += a(i, k);
        }
    }

    return *this;
}
template double&MatrixBase::operator()(int行,int列)
{
返回静态_cast(*this).operator()(行,列);
}
模板双MatrixBase::operator()(int行,int列)常量
{
返回静态_cast(*this).operator()(行,列);
}
模板T&MatrixBase::运算符=(双值)
{
返回静态_cast(*this).operator=(值);
}
模板T&MatrixBase::运算符=(T&a)
{
返回静态_cast(*this).operator=(a);
}
//将另一个衍生矩阵添加到此衍生矩阵
模板T&MatrixBase::运算符+=(T&a)
{
返回静态_cast(*this).operator+=(a);
}
双精度矩阵::运算符()(int行,int列)
{
REQUIRE(行>=0&&col>=0,“错误:索引必须是非负的”);
REQUIRE(行<行&&col<列&,“错误:矩阵外的元素索引”);
返回数据[行][col];
}
双矩阵::运算符()(int行,int列)常量
{
REQUIRE(行>=0&&col>=0,“错误:索引必须是非负的”);
REQUIRE(行<行&&col<列&,“错误:矩阵外的元素索引”);
返回数据[行][col];
}
/*****************************************************************************
*目的:将整个矩阵初始化为指定值。
******************************************************************************/
矩阵和矩阵::运算符=(双值)
{
对于(int i=0;irows()-1数据返回(pfstl::vectrain());
this->rows++;//我们添加了一个新行
}
int iteratedCols=0;
while(iteratedColscols()-1数据[iteratedRows]。向后推(a(iteratedRows,iteratedCols));
}
其他的
{
这->数据u[iteratedRows][iteratedCols]=a(iteratedRows,iteratedCols);
}
迭代cols++;
}
iteratedRows++;
}
//如果a的行数少于此,则强制此行数与a的行数相同
而(a.rows()rows)
{
//为了使大小相等,从后面移除多余的行
此->数据擦除(结束(此->数据));
这个->行--;
}
//与上述列的逻辑相同
而(a.cols()cols)
{
对于(int i=0;irows\uu;i++)
{
此->数据[i]。擦除(结束(此->数据[i]);
}
这个->科尔斯--;
}
这->行=a.行();
这->cols_uz=a.cols();
归还*这个;
}
//将另一个衍生矩阵添加到此衍生矩阵
矩阵和矩阵::运算符+=(常数矩阵和a)
{
REQUIRE(rows_==a.rows(),“错误:矩阵加法需要相同数量的行。”);
REQUIRE(cols_==a.cols(),“错误:矩阵加法需要相同数量的列。”);
对于(int i=0;i
头文件:

template <typename T> class MatrixBase
{
public:
    // These methods must be implemented for each deriving class

    double& operator()(int row, int col);
    double operator()(int row, int col) const;

    T& operator=(double value);
    T& operator=(T& a);

    // Add another derived Matrix to this derived Matrix
    T& operator+=(T& a);
}

class Matrix : public MatrixBase<Matrix>
{
public:
    // Constructors
    Matrix();
    Matrix(int row, int cols);
    // Destructor
    ~Matrix();

    double& operator()(int row, int col);
    double operator()(int row, int col) const;

    Matrix& operator=(double value);
    Matrix& operator=(const Matrix& a);

    // Add another derived Matrix to this derived Matrix
    Matrix& operator+=(const Matrix& a);
}
模板类MatrixBase
{
公众:
//必须为每个派生类实现这些方法
double&运算符()(int行,int列);
双运算符()(int行,int列)常量;
T&运算符=(双值);
T&a算子=(T&a);
//将另一个衍生矩阵添加到此衍生矩阵
T&a操作员+=(T&a);
}
类矩阵:公共矩阵库
{
公众:
//建设者
矩阵();
矩阵(int行,int列);
//析构函数
~Matrix();
double&运算符()(int行,int列);
双运算符()(int行,int列)常量;
矩阵和运算符=(双值);
矩阵
struct NotCopyable
{
    NotCopyable() {}
    NotCopyable(const NotCopyable&) = delete;
};

template <typename T>
void foo(T t)
{
    (void)static_cast<T>(t);
}

template <typename T>
void bar(T& t)
{
    (void)static_cast<T&>(t);
}

int main()
{
    NotCopyable c;
    foo(c);
    bar(c);
}
struct Base
{
    virtual ~Base() {}
};

struct Derived : Base {};

template <typename T>
void foo(T t)
{
    (void)static_cast<Derived>(t);
}

template <typename T>
void bar(T& t)
{
    (void)static_cast<Derived&>(t);
}

int main()
{
    Derived c;
    foo<Base>(c);
    bar<Base>(c);
}