我有一个Matrix
类,其中包含一个成员变量std::list<Element> listMatrix;
。 Element
是一个类,它有3个int
类型的成员变量line, column, value
。我将矩阵中不为0的元素的行、列和值保存在列表中。我想重载operator [][]
,这样我就可以像这样做:Matrix a;
a[2][3] = 5;
。我知道你不能直接overload [][]
。
我有一个Matrix
类,其中包含一个成员变量std::list<Element> listMatrix;
。 Element
是一个类,它有3个int
类型的成员变量line, column, value
。我将矩阵中不为0的元素的行、列和值保存在列表中。我想重载operator [][]
,这样我就可以像这样做:Matrix a;
a[2][3] = 5;
。我知道你不能直接overload [][]
。
请对 Element& operator()(int, int)
(以及其const
版本)进行重载,以便您可以编写如下代码:
matrix(2, 3) = 5;
[2][3]
的语法,你需要定义一个代理类,这样matrix[2]
就会返回一个代理值,proxy[3]
则会返回所需的引用。但这会带来很多问题。基本思路如下:class naive_matrix_2x2
{
int data[4];
struct proxy
{
naive_matrix_2x2& matrix;
int x;
int& operator[](int y) { return matrix.data[x*2+y]; }
};
public:
proxy operator[](int x) { return {*this, x}; }
};
[2][3]
这样做。我在其他问题中读到了关于代理类的内容,但是我不知道它是如何工作以及如何实现的。是否有更深入或更长的解释,以及如何解决相关问题?另外,在重载[][]之后,当我写matrix[2][3] = 0
时,是否可能使其从列表中删除元素(2,3,value)
,因为它变成了0,而我只想在列表中保留非零元素。 - Ovidiu Firescuoperator=
)。这不是一个好主意(商标)。 - YSCclass Row
是我给我的命名方式。 - MSalters列表不适合使用下标运算符作为容器,因为它没有直接访问其元素的方法,必须通过移动迭代器来查找。因此,使用该运算符效率低下。
最好使用标准容器 std::vector
,它已经具有下标运算符。
尽管如此,回答您的问题,可以按照以下方式定义该运算符。您可以在运算符中添加异常处理,然后索引将指向列表之外的位置。
#include <iostream>
#include <list>
struct A
{
int x, y, z;
int & operator []( size_t n )
{
return n == 0 ? x : n == 1 ? y : z;
}
const int & operator []( size_t n ) const
{
return n == 0 ? x : n == 1 ? y : z;
}
};
struct B
{
std::list<A> lst;
A & operator []( size_t n )
{
auto it = std::begin( lst );
for ( ; n; n-- ) std::advance( it, 1 );
return *it;
}
const A & operator []( size_t n ) const
{
auto it = std::begin( lst );
for ( ; n; n-- ) std::advance( it, 1 );
return *it;
}
};
int main()
{
B b = { { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } } };
std::cout << b[0][0] << '\n';
std::cout << b[0][1] << '\n';
std::cout << b[0][2] << '\n';
b[2][1] += 20;
std::cout << b[2][1] << '\n';
}
1
2
3
28
b[1][2] b[4][5] b[7][8]
,这三个元素的输出应为3 6 9
,其余元素应为0,因为它们不在列表中。感谢您的回答。 - Ovidiu Firescu
list
的原因是什么?由于数据的局部性(即较少的缓存未命中),vector
很可能更快。而且我不会经常期望矩阵在中间插入元素... - 463035818_is_not_a_numberlist
因为问题规定了必须使用列表。 - Ovidiu Firescu