重载多维括号 [英] Overloading multi-dimensional brackets

查看:68
本文介绍了重载多维括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何重载多维括号?

比方说,我有一个可以让我访问 n -向量空间中的点的类.例如:

Let's say that I have a class which enables me to access points in an n-vector space. For example:

class NSpaceVector {
    private:
        int vectorSpace[8][8][8][8][8][8][8];
    public:        
        const NSpaceVector operator[][][][][][][](int i, int j, int k, int l, int m, int n, int p)const {return vectorSpace[i][j][k][l][m][n][p]; }
        NSpaceVector operator[][][][][][][](int i, int j, int k, int l, int m, int n, int p) {return vectorSpace[i][j][k][l][m][n][p]; }
}
unsigned long & operator [](int i) {return registers[i];}

我想做的就是重载括号运算符,这样我就可以像这样索引到这个位置:

What I would like to do is overload the bracket operator so that I can index into this location like so:

int main() {
    NSpaceVector nsv; // Assume initializes all to 0
    nsv[2][4][7][4][0][7][6] = 2;
    cout << nsv[2][4][7][4][0][7][6] << endl; //-> 2
    cout << nsv[1][4][7][4][0][7][6] << endl; //-> 0
    return 0;
}

我无法编译它.有任何想法吗? Thx,Keith:^)

I can't get this to compile. Any ideas? Thx, Keith :^)

推荐答案

标准答案是让每个[](从左到右)返回正确的嵌套子集的代理,最后一个子集实际返回对数据的引用.在您的方案中,到目前为止,最简单的方法是对嵌套类型进行模板化以实现生产自动化.

The standard answer is to have each [] (from left-to-right) return a proxy for the correct nested subset, the last of which actually returns a reference to the data. In your scheme, it would be easiest by far to template the nested types to automate production.

正如神秘的user4581301所提到的,提供它要简单得多

As the mysterious user4581301 mentions, it's much simpler to provide

nsv(2,4,7,4,0,7,6)


所需类的示例模板生成可能比使用临时代理对象更简单:


Sample template production of your desired class is probably simpler than using a temporary proxy object:

template <size_t Width, size_t Depth, typename T=int>
struct SubSpace;

template <size_t Width, typename T>
struct SubSpace<Width,0,T> {
    std::array<T, Width> array;

    T& operator[] (size_t i) { return array[i]; }
    T const& operator[] (size_t i) const { return array[i]; }
};

template <size_t Width, size_t Depth, typename T>
struct SubSpace {
    using Nested = SubSpace<Width, Depth-1, T>;
    std::array<Nested, Width> array;

    Nested& operator[] (size_t i) { return array[i]; }
    Nested const& operator[] (size_t i) const { return array[i]; }
};


using NSpaceVector = SubSpace<8,6>;

int main()
{
    NSpaceVector nsv;
    nsv[2][4][7][4][0][7][6] = 2;
    cout << nsv[2][4][7][4][0][7][6] << endl; //-> 2
}

请注意,这目前还没有默认初始化数组成员,但是我们仍然可以使用聚合初始化:

Note this doesn't currently default-initialize the array members, but we can use aggregate initialization anyway:

    NSpaceVector nsv {}; // value-initialize every element
    nsv[2][4][7][4][0][7][6] = 2;
    cout << nsv[2][4][7][4][0][7][6] << endl; //-> 2
    cout << nsv[2][4][7][4][0][7][5] << endl; //-> 0

还要注意,SubSpace<8,6>给出了您想要的8x7结果,因为深度在0处终止.这可以用顶级包装程序清除,但是我不愿意在Depth==1处终止,并且在发生错误时一切都会出错有人无意中实例化了SubSpace<0,0>.

Also note that SubSpace<8,6> gives the 8x7 result you wanted, since Depth terminates at 0. This could be cleaned up with a toplevel wrapper, but I'm reluctant to terminate on Depth==1 instead and have everything go wrong when someone instantiates SubSpace<0,0> by accident.

更简单,这取决于您是否要在课堂中任何行为:

Simpler still, depending on whether you want any behaviour in your class, is this:

struct OtherSpaceVector {
    int s[8][8][8][8][8][8][8];

    auto operator[] (size_t i) -> decltype(s[i]) { return s[i]; }
};

int main()
{
    OtherSpaceVector osv{};
    osv[2][4][7][4][0][7][6] = 2;
    std::cout << osv[2][4][7][4][0][7][6] << '\n'; 
    std::cout << osv[2][4][7][4][0][7][5] << '\n';
}

更改尺寸和感觉比模板版本更难,但是它仍然适用于您提供的用例.

It's harder to alter the dimensions and feels more brittle than the template version, but it still works for the use case you provided.

这篇关于重载多维括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆