1

我自己开发了一个基于表达式模板的 C++ 矩阵类。我还实现了一个Range类来启用类似 Matlab 的读取

cout << A(Range(3,5),Range(0,10)) << endl;

我现在想启用类似 Matlab 的作业

A(Range(3,5),Range(0,10))=B;

其中B是一个合适的矩阵。

运算Matrix ()符重载如下

inline Expr<SubMatrixExpr<const OutType*,OutType>,OutType> operator()(Range range1, Range range2)
{   typedef SubMatrixExpr<const OutType*,OutType> SExpr; 
    return Expr<SExpr,OutType>(SExpr(...some stuff...),...some stuff...); 
}

该类SubMatrixExpr示例为

template <class A, class Type>
class  SubMatrixExpr
{
    // Constructor (M is a pointer to the Matrix data)
    SubMatrixExpr(const A &M, ...stuff...) : ...stuff...    

    // Access operator
    inline Type operator[](const int i) const { ...stuff... }
}

Expr类的例子如下:

template <class A, class B>
class Expr
{
    // Constructor (a is the expression, the SubMatrixExpr in my case)
    Expr(const A &a, ...stuff...) : ...stuff...

    // Access
    inline B operator[](const int i) const { return a_[i]; }

    Expr<A,B> operator=(const Matrix<B> &ob)
    {
        for (int i=0; i<GetNumElements(); i++) { std::cout << a_[i] << " " << ob.GetDataPointer()[i] << "\n"; a_[i] = ob.GetDataPointer()[i]; }
        return *this;
    }
}

我的问题如下。我const在上面的两个表达式类的访问运算符中使用。结果是类的重载=运算符Expr正确返回a_[i]and ob.GetDataPointer()[i],但它没有进行赋值。

是否可以在不更改整个代码的情况下忽略const重载运算符中的 -ness ?=

非常感谢您的帮助。

按照 Lol4t0 的回答进行编辑

我已经删除了该Expr课程的原始访问运算符并添加了

inline const B& operator[](const int i) const { return a_[i]; }
inline  B& operator[](const int i)  
{ 
    const Expr& constThis = *this;
    return const_cast<B&>(constThis[i]); 
}

另外,我已经删除了我原来的访问运算符SubMatrixExpr并添加了

inline const Type& operator[](const int i) const
{
    // Stuff
    return M_[IDX2R(GlobalRow,GlobalColumn,Columns_up_)];
}

inline Type& operator[](const int i) 
{
    // Stuff
    // The following line returns an error
    return M_[IDX2R(GlobalRow,GlobalColumn,Columns_up_)];
}

不幸的是,编译器返回以下错误

qualifiers dropped in binding reference of type "LibraryNameSpace::double2_ &" to initializer of type "const LibraryNameSpace::double2_"    

double2_是我自己的复杂类型)。

编辑#2 - 关于 M_ 的信息

template <class A, class Type>
class  SubMatrixExpr
{
    private:
   A M_;

    // STUFF
}

Matrix ()上面报告的运算符重载中,对于我当前正在运行的示例,矩阵类型A = const OutType*在哪里。OutTypedouble2_

4

1 回答 1

2

这实际上不是 constenss 问题。您在's中按值返回。operator []因此,返回的值被复制,并且您为副本分配新值,该值被销毁。

实际上,您的代码是这样工作的

struct S
{
    int v;
} x = {0};
S foo() { return x;}
int main() 
{
    foo() = {1}; 
    std::cout << foo().v;
}

当然,它不会保存您分配的新值。

通常容器有 2 个重载operator[]

  • 第一个重载对常量容器进行操作,并通过常量引用返回。

    const Type& operator[](const int i) const { ...stuff... }
    const B& operator[](const int i) const { return a_[i]; }
    
  • 第二个重载适用于可变容器并通过引用返回,因此可以修改容器项:

    Type& operator[](const int i) { ...stuff... }
    B& operator[](const int i) { return a_[i]; }
    

原则上,可变版本可以通过常量一来实现:

B& Class::operator[](const int i) 
{
const Class& constThis = *this;
return const_cast<B&>(constThis[i]);
}
于 2013-05-09T21:01:36.393 回答