如何解决有没有更好的方法来实现成员函数 row() 的 const 版本而不使用 const_cast?
示例来自 std::slice 和 std::slice_array 的使用演示:
https://en.cppreference.com/w/cpp/numeric/valarray/slice
https://en.cppreference.com/w/cpp/numeric/valarray/slice_array
我应该如何正确定义成员函数 row() 的 const 版本?下面的代码可以编译,但它使用 const_cast。如果您能提出任何建议,我将不胜感激。
#include <iostream>
#include <valarray>
class Matrix {
std::valarray<int> data;
int dim;
public:
Matrix(int r,int c) : data(r*c),dim(c) {}
int& operator()(int r,int c) {return data[r*dim + c];}
std::slice_array<int> row(std::size_t row) {
return data[std::slice(dim*row,dim,1)];
}
const std::slice_array<int> row(std::size_t row) const {
return const_cast<std::valarray<int>&>(data)[std::slice(dim*row,1)];
}
};
int main()
{
Matrix m(3,3);
int n = 0;
for(int r=0; r<3; ++r)
for(int c=0; c<3; ++c)
m(r,c) = ++n;
const Matrix m2(m);
for(int r=0; r<3; ++r) {
for(int c=0; c<3; ++c) {
std::cout << m(r,c) << " ";
}
std::cout << std::endl;
}
// non-const
std::slice_array<int> isa = m.row(0);
std::valarray<int> iva(isa);
for (auto elem : iva) { std::cout << elem << std::endl;}
// const
const std::slice_array<int> isa2 = m2.row(0);
const std::valarray<int> iva2(isa2);
for (auto elem : iva) { std::cout << elem << std::endl;}
return 0;
}
如果成员函数定义如下:
const std::slice_array<int> row(std::size_t row) const {
return data[std::slice(dim*row,1)];
}
然后产生以下错误信息:
valarray_demo.cpp:13:16: error: no viable conversion from returned value of type '__val_expr<__slice_expr<const std::__1::valarray<int> &> >' to function return type 'const std::slice_array<int>'
return data[std::slice(dim*row,1)];
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/valarray:1149:28: note: candidate constructor (the implicit copy constructor) not viable: no kNown conversion from
'__val_expr<__slice_expr<const std::__1::valarray<int> &> >' to 'const std::__1::slice_array<int> &' for 1st argument
class _LIBCPP_TEMPLATE_VIS slice_array
测试: macOS 卡特琳娜; Apple clang 版本 11.0.3 (clang-1103.0.32.29)
解决方法
请注意,在返回值类型 const std::slice_array<int>
中,顶级 const
限定符被编译器忽略,因此实际返回类型为 std::slice_array<int>
。 The same rule applies to function parameters.
您可能需要对常量元素的切片,而不是对可变元素的常量切片。
std::valarray
doesn't offer slices to constant elements:
std::slice_array<T> operator[](std::slice slicearr);
std::valarray<T> operator[](std::slice slicearr) const;
const
版本返回元素的副本,因此根本无法实现将切片返回到常量元素。
std::valarray
是一个奇怪的野兽,长期被放弃的 C++ 标准库中线性代数支持的尝试。对于生产代码,您可能喜欢使用 Eigen 库:Eigen is a C++ template library for linear algebra: matrices,vectors,numerical solvers,and related algorithms。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。