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);
}