为稀疏向量重载operator []

Tho*_*mas 6 c++ operator-overloading sparse-matrix subscript

我正在尝试用C++创建一个"稀疏"矢量类,如下所示:

template<typename V, V Default>
class SparseVector {
    ...
}
Run Code Online (Sandbox Code Playgroud)

在内部,它将由a表示std::map<int, V>(其中V存储的值的类型).如果地图中不存在元素,我们将假装它等于Default模板参数中的值.

但是,我在重载下标运算符时遇到问题[].我必须重载[]操作符,因为我将此类中的对象传递给期望[]正常工作的Boost函数.

const版本是很简单的:检查索引是否在地图上,它的返回值,如果是这样,或者Default以其他方式.

但是,非const版本要求我返回一个引用,这就是我遇到麻烦的地方.如果只读取值,我不需要(也不想)向地图添加任何内容; 但如果正在编写,我可能需要在地图中添加一个新条目.问题是重载[]不知道是读取还是写入值.它只返回一个引用.

有什么方法可以解决这个问题吗?或者也许要解决它?

Ste*_*sop 13

可能有一些非常简单的技巧,但我认为operator[]只需返回可以从V(并转换为V)分配的东西,不一定是V&.所以我认为你需要返回一个带有重载的对象operator=(const V&),这会在稀疏容器中创建一个条目.

但是,您必须检查Boost函数对其模板参数的作用 - 用户定义的V转换会影响转换链的可能性,例如,防止在同一个链中再进行任何用户定义的转换.


Fre*_*abe 9

不要让非const运算符和实现返回引用,而是返回代理对象.然后,您可以实现代理对象的赋值运算符,以区分对operator []的读访问和写访问.

这里有一些代码草图来说明这个想法.这种方法并不漂亮,但很好 - 这就是C++.C++程序员不会浪费时间参加选美比赛(他们也不会有机会).;-)

template <typename V, V Default>
ProxyObject SparseVector::operator[]( int i ) {
   // At this point, we don't know whether operator[] was called, so we return
   // a proxy object and defer the decision until later
   return ProxyObject<V, Default>( this, i );
}

template <typename V, V Default>
class ProxyObject {
    ProxyObject( SparseVector<V, Default> *v, int idx );
    ProxyObject<V, Default> &operator=( const V &v ) {
      // If we get here, we know that operator[] was called to perform a write access,
      // so we can insert an item in the vector if needed
    }

    operator V() {
      // If we get here, we know that operator[] was called to perform a read access,
      // so we can simply return the existing object
    }
};
Run Code Online (Sandbox Code Playgroud)