c++ - 错误:没有用于初始化 'Matrix_ref<...>' 的匹配构造函数
问题描述
我正在学习 C++,所以请耐心等待。
这是我的矩阵类
template<class T = double> class Matrix {
using sequence_type = std::vector<T>;
public:
... some methods and constructors
Matrix_ref<T> col(Index i_) { if (i_ < 0 || i_ > r) _error("out_of_bound"); return Matrix_ref<T>(elems.data(), Matrix_slice(i_, r, c), r); }
Matrix_ref<T> row(Index i_) { if (i_ < 0 || i_ > c) _error("out_of_bound"); return Matrix_ref<T>(elems.data(), Matrix_slice(i_ * c, c, 1), c); }
const Matrix_ref<T> col(Index i_) const { if (i_ < 0 || i_ > r) _error("out_of_bound"); return Matrix_ref<T>(elems.data(), Matrix_slice(i_, r, c), r); }
const Matrix_ref<T> row(Index i_) const { if (i_ < 0 || i_ > c) _error("out_of_bound"); return Matrix_ref<T>(elems.data(), Matrix_slice(i_ * c, c, 1), c); }
Matrix_ref<T> operator[](Index r_) { return row(r_); }
private:
sequence_type elems;
Index r;
Index c;
...other methods
};
这是一个返回行中元素的正确索引的结构(实际上它计算“步幅”)
struct Matrix_slice {
Matrix_slice(Index first_, Index size_, Index stride_) : first(first_), size(size_), stride(stride_) {}
const Index first;
const Index size;
const Index stride;
Index operator()(Index i) { return first + stride * i; }
const Index operator()(Index i) const { return first + stride * i; }
};
这是对矩阵的“参考”。如果我对矩阵使用 [] 运算符,我会得到一个 matrix_ref。
template<class T = double> class Matrix_ref {
public:
Matrix_ref(T* elems_, Matrix_slice slice_, Index ref_size_) : elems(elems_), slice(slice_), ref_size(ref_size_) {}
T& at(Index i) { if (i < 0 || i >= ref_size) _error("out_of_bound"); return elems[slice(i)]; }
const T& at(Index i) const { if (i < 0 || i >= ref_size) _error("out_of_bound"); return elems[slice(i)]; }
T& operator[](Index i) { return elems[slice(i)]; }
const T operator[](Index i) const { return elems[slice(i)]; }
constexpr Index size() const { return ref_size; }
private:
T* elems;
const Matrix_slice slice;
const Index ref_size;
};
这是 operator* 的定义:
template<class T> Matrix<T> operator*(const Matrix<T>& a, const Matrix<T>& b) {
if (a.cols() != b.rows()) _error("Matrix size mismatch");
Matrix<T> res(a.rows(), b.cols());
for (Index i = 0; i < res.rows(); ++i)
for (Index j = 0; j < res.cols(); ++j)
res.at(i, j) = a.row(i) * b.col(j);
return res;
}
问题在这里 -> operator*(const Matrix& a, const Matrix& b) 如果我用 const Matrix& a 和 const...b 声明这个运算符,它不起作用,但如果我声明没有 const 关键字,它会起作用。但我认为使用 const 会更好。我该如何解决?我认为问题在于 Matrix_ref 没有将 T* elems 声明为 const。如果我将它声明为 const,它可以工作,但我不能修改 Matrix。我在返回 Matrix 类中的 row/col 方法时遇到错误,这是由这一行“res.at(i, j) = a.row(i) * b.col(j);”引起的 在重载 operator* 函数中。
解决方案
正如你所说,问题在于constness。
const Matrix_ref<T> col(Index i_) const
{
if (i_ < 0 || i_ > r) _error("out_of_bound");
return Matrix_ref<T>(elems.data(), Matrix_slice(i_, r, c), r); // <--
}
当您elems.data()
从const方法vector<T>::data()
返回调用时const T*
,编译器会抱怨,因为const T*
无法分配给T*
- 修改数据的风险。但是,您知道row
andcol
方法返回
代理类的const对象, const Matrix_ref<T>
因此您可以用来
const_cast
从 中删除 const elemes.data()
,代理类的实例将保留指向 的指针T
,并且由于返回的对象是合格的,因为const
只能在此对象上调用const方法,因此防止在Matrix
您使用代理类时修改数据。在这种情况下使用是安全的,因此您可以按如下const_cast
方式更改row
和成员函数:col
const Matrix_ref<T> col(Index i_) const {
if (i_ < 0 || i_ > r) _error("out_of_bound");
return Matrix_ref<T>( const_cast<T*>(elems.data()) , Matrix_slice(i_, r, c), r);
} // ^^^
推荐阅读
- reactjs - 无法修复错误:找不到模块'webpack-cli/bin/config-yargs'
- html - Bootstrap 5 表单上的水平和垂直中心
- c# - 为什么我的应用程序在 300 条记录后停止工作?
- reactjs - 为什么我不能在我的项目中实现 React Helmet?
- elasticsearch - 如何通过 SpringBoot API 在 Elasticsearch 中检索超过 10K 条记录
- java - 如何创建没有参数的临时对象
- excel - Excel : 使用 Excel 一个表格中的数据来计算另一个表格中的值
- ionic-framework - 在 React / Ionic 5 中设置离子选择的默认值
- c# - 如何使用正则表达式识别特定行?C#
- java - 使用 Jersey 3 和 Tomcat 10 的 Hello World 问题/404