微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有更好的方法来实现成员函数 row() 的 const 版本而不使用 const_cast?

如何解决有没有更好的方法来实现成员函数 row() 的 const 版本而不使用 const_cast?

示例来自 std::slicestd::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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?