多维数组:运算符重载
Multidimensional array: operator overloading
我有一个带有多维数组的类:
-
可以创建一、二、。。。,具有此类的n维阵列
-
如果数组有n个维度,我想使用n个
operator[]
来获得一个对象:
示例:
A a({2,2,2,2}];
a[0][1][1][0] = 5;
但数组不是指向其他向量等的指针的向量。
所以我希望操作符[]返回一个类对象,直到最后一个维度,然后返回一个整数
这是一个非常简化的代码,但它显示了我的问题:
我收到的错误:"[Error] cannot convert 'A::B' to 'int' in initialization"
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <iostream> // cin, cout...
class A {
private:
static int* a;
public:
static int dimensions;
A(int i=0) {
dimensions = i;
a = new int[5];
for(int j=0; j<5; j++) a[j]=j;
};
class B{
public:
B operator[](std::ptrdiff_t);
};
class C: public B{
public:
int& operator[](std::ptrdiff_t);
};
B operator[](std::ptrdiff_t);
};
//int A::count = 0;
A::B A::operator[] (std::ptrdiff_t i) {
B res;
if (dimensions <= 1){
res = C();
}
else{
res = B();
}
dimensions--;
return res;
}
A::B A::B::operator[] (std::ptrdiff_t i){
B res;
if (dimensions <=1){
res = B();
}
else{
res = C();
}
dimensions--;
return res;
}
int& A::C::operator[](std::ptrdiff_t i){
return *(a+i);
}
int main(){
A* obj = new A(5);
int res = obj[1][1][1][1][1];
std::cout<< res << std::endl;
}
operator[]
在obj[1][1]...[1]
中从左到右求值,因此obj[1]
返回一个B
对象。假设现在您只有int res = obj[1]
,那么您将为B
对象(或者在多次调用[]
的情况下为C
对象)分配int
,但没有从B
或C
到int
的转换。您可能需要编写一个转换运算符,如
operator int()
{
// convert to int here
}
对于A
、B
和C
,因为重载运算符不被继承。
我只是通过为A
和B
编写这样的运算符就消除了您的编译错误(当然,我也有链接错误,因为有未定义的函数)。
此外,请注意,如果要编写类似obj[1][1]...[1] = 10
的内容,则需要重载operator=
,因为从int
到A
或代理对象没有隐式转换。
希望这是有道理的。
附言:另请参阅@Oncaphillis的评论!
vsoftco是完全正确的,如果您想实际访问元素,则需要实现重载运算符。如果你想让它是动态的,这是必要的,这就是你描述它的方式。我实际上认为这是一个有趣的问题,所以我实现了你描述的模板。我认为它是有效的,但有些地方可能有点偏离
template<typename T>
class nDimArray {
using thisT = nDimArray<T>;
T m_value;
std::vector<thisT*> m_children;
public:
nDimArray(std::vector<T> sizes) {
assert(sizes.size() != 0);
int thisSize = sizes[sizes.size() - 1];
sizes.pop_back();
m_children.resize(thisSize);
if(sizes.size() == 0) {
//initialize elements
for(auto &c : m_children) {
c = new nDimArray(T(0));
}
} else {
//initialize children
for(auto &c : m_children) {
c = new nDimArray(sizes);
}
}
}
~nDimArray() {
for(auto &c : m_children) {
delete c;
}
}
nDimArray<T> &operator[](const unsigned int index) {
assert(!isElement());
assert(index < m_children.size());
return *m_children[index];
}
//icky dynamic cast operators
operator T() {
assert(isElement());
return m_value;
}
T &operator=(T value) {
assert(isElement());
m_value = value;
return m_value;
}
private:
nDimArray(T value) {
m_value = value;
}
bool isElement() const {
return m_children.size() == 0;
}
//no implementation yet
nDimArray(const nDimArray&);
nDimArray&operator=(const nDimArray&);
};
基本思想是,这个类既可以充当数组的数组,也可以充当元素。这意味着事实上,数组的数组可以是元素的数组!当您想要获取一个值时,它会尝试将其强制转换为一个元素,如果不起作用,它只会抛出一个断言错误。
希望这是有意义的,当然,如果你有任何问题,请走开!事实上,我希望你能问,因为你描述的问题的范围比你想象的要大。
使用俄罗斯娃娃风格的模板类可能会很有趣。
// general template where 'd' indicates the number of dimensions of the container
// and 'n' indicates the length of each dimension
// with a bit more template magic, we could probably support each
// dimension being able to have it's own size
template<size_t d, size_t n>
class foo
{
private:
foo<d-1, n> data[n];
public:
foo<d-1, n>& operator[](std::ptrdiff_t x)
{
return data[x];
}
};
// a specialization for one dimension. n can still specify the length
template<size_t n>
class foo<1, n>
{
private:
int data[n];
public:
int& operator[](std::ptrdiff_t x)
{
return data[x];
}
};
int main(int argc, char** argv)
{
foo<3, 10> myFoo;
for(int i=0; i<10; ++i)
for(int j=0; j<10; ++j)
for(int k=0; k<10; ++k)
myFoo[i][j][k] = i*10000 + j*100 + k;
return myFoo[9][9][9]; // would be 090909 in this case
}
每个维度都保留一个以前维度元素的数组。维度1使用跟踪1D int数组的基本专门化。维度2将保持一维数组的数组,D3将具有二维数组的数组等。然后访问看起来与本地多维数组相同。在我的例子中,我在类中使用数组。这使得n维数组的所有内存都是连续的,并且不需要在类内部进行动态分配。但是,您也可以通过动态分配提供相同的功能。
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- C++20概念:需要运算符重载
- 使用赋值运算符重载从类中返回jobject
- 在运算符重载定义中使用成员函数(const错误)
- 字节到位运算符重载C++
- 为什么在运算符重载时需要参考?
- 类中 c++ 的运算符 + 重载
- 算术复合运算符重载为非成员
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 交换运算符 + 重载会导致无限递归
- 如何理解新的运算符重载?
- 向量保持复数的运算符重载
- 如何创建运算符重载?
- 链接列表运算符重载没有打印出我想要的内容
- C++:需要帮助了解运算符重载错误
- 使用模板化运算符重载 XOR 运算符失败
- 如何确保接受的C++模板类型使运算符重载?
- 运算符重载使用运算符+添加类模板