C++ [] 具有多个参数的数组运算符?

发布于 2024-08-15 22:16:30 字数 392 浏览 7 评论 0 原文

我可以在 C++ 中定义一个带有多个参数的数组运算符吗?我这样尝试:

const T& operator[](const int i, const int j, const int k) const{ 
    return m_cells[k*m_resSqr+j*m_res+i];
}

T& operator[](const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

但我收到此错误:

error C2804 binary operator '[' has too many parameters

Can I define in C++ an array operator that takes multiple arguments? I tried it like this:

const T& operator[](const int i, const int j, const int k) const{ 
    return m_cells[k*m_resSqr+j*m_res+i];
}

T& operator[](const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

But I'm getting this error:

error C2804 binary operator '[' has too many parameters

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

£噩梦荏苒 2024-08-22 22:16:30

在 C++23 之前,您无法重载 operator[] 来接受多个参数。作为解决方法,您可以重载 operator()。 (请参阅如何为 Matrix 类创建下标运算符? 来自 C++ FAQ。)


来自 C++23,如 answer 中提到的https://stackoverflow.com/users/8372853">cigien,可以将多个下标参数传递给直接操作符[]。请参阅 cppreference 页面中的演示

Prior to C++23, you could not overload operator[] to accept multiple arguments. As a workaround, you instead can overload operator(). (See How do I create a subscript operator for a Matrix class? from the C++ FAQ.)


From C++23, as mentioned in a (deleted) answer by cigien, multiple subscript arguments can be passed to operator[] directly. See this demo from the cppreference page.

澉约 2024-08-22 22:16:30

不可能重载[]运算符来接受多个参数,但替代方法是使用代理模式

用两个词来说:a[x][y],第一个表达式 (a[x]) 将返回一个不同的类型,名为代理类型,该类型将有另一个 <代码>运算符[]。它会调用原始类的 _storedReferenceToOriginalObject->At(x,y) 之类的内容。

您将无法执行 a[x,y],但我猜您无论如何都想重载通常的 C++ 风格的 2D 数组语法。

It is not possible to overload the [] operator to accept multiple arguments, but an alternative is to use the proxy pattern.

In two words: a[x][y], the first expression (a[x]) would return a different type, named proxy type, which would have another operator[]. It would call something like _storedReferenceToOriginalObject->At(x,y) of the original class.

You will not be able to do a[x,y], but I guess you wanted to overload the usual C++-style 2D array syntax anyway.

夏见 2024-08-22 22:16:30

您可以使用 C++11 中提供的统一初始化语法来实现一个不错的小技巧。您不直接获取索引,而是获取 POD。

struct indices
{
  std::size_t i, j, k;
};

T& operator[](indices idx)
{
  return m_cells[idx.k * m_resSqr + idx.j * m_res + idx.i];
}

然后使用新语法:

my_array<int> arr;
// ...
arr[{1, 2, 3}] = 42;

There's a nice little trick you can do with the uniform initialization syntax available in C++11. Instead of taking the index directly, you take a POD.

struct indices
{
  std::size_t i, j, k;
};

T& operator[](indices idx)
{
  return m_cells[idx.k * m_resSqr + idx.j * m_res + idx.i];
}

And then use the new syntax:

my_array<int> arr;
// ...
arr[{1, 2, 3}] = 42;
与之呼应 2024-08-22 22:16:30

为了完整起见:有一种方法可以实际使用带有多个参数的括号运算符,如果它们不是基本数据类型,
通过重载逗号运算符而不是括号运算符,请参阅以下有关逗号重载的文章:

https:/ /stackoverflow.com/a/18136340/5836981

免责声明:在我看来,重载逗号运算符很容易出错,并使代码更加晦涩,只有在更奇特的情况下才值得考虑。我添加这个答案是因为我在一些代码中遇到了这个实例,我花了一段时间才发现关键不是 [] 运算符(不能用多个参数重载),而是 , 运算符。

For completeness sake: There is a way to actually use the bracket operator with multiple arguments, if they are not basic data types,
namely by overloading the comma operator and not the bracket operator, see the following post about comma overloading:

https://stackoverflow.com/a/18136340/5836981

Disclaimer: in my opinion overloading the comma operator is error prone and renders code more obscure, and is worth considering only in more exotic cases. I added this answer because I came over an instance of this in some code and it took me a while to figure out that the key was not the [] operator (which cannot be overloaded with multiple arguments) but the ,operator.

彩扇题诗 2024-08-22 22:16:30

编辑:正如评论中指出的,在C++20中,运算符逗号将被弃用,因此如下答案。

您无法重载 operator[],但您可以通过重载 operator, 来伪造它

按照您的代码,它变成:

T& operator,(const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

现在您将能够调用

something[1, 2, 3]

您可以使用模板、带有可变参数的模板、std::pairstd::tuple 来扩展它,具体取决于根据您的用例和 C++ 版本

Edit: as pointed in comment, in C++20 operator comma will be deprecated, so as the answer below.

You can't overload operator[], but you can fake it by overloading operator, instead.

Following your code it becomes:

T& operator,(const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

now you'll be able to call

something[1, 2, 3]

You can extend it using templates, templates with variadic arguments, std::pair or std::tuple depending on your use case and C++ version

以可爱出名 2024-08-22 22:16:30

C++ 中任意类型和大小的 N 维数组:

这个答案受到 Pavel Radzivilovsky 答案的启发,谢谢。我在实现实现时遇到了一些困难,因为这是我第一次尝试递归模板。我想分享我所做的事情,以便其他人可以比我更快地理解。

我编写了一个 C++ 模板类来创建任意类型和大小的 n 维数组。它需要用数组类型和维数来实例化。大小可以动态改变。我在下面给出了如何创建多维数组的裸(剥离)工作版本,可以通过连续应用运算符[]来访问其中的元素(例如 array[x][y] [z])。此版本只能处理维度 n>1 的数组。 main 函数以如何创建 4 维整数数组为例。

编辑:请记住,为了便于阅读,下面的示例是最小的,因为它不会释放数组,也不会对访问进行边界检查。添加这个是微不足道的,留给程序员。

#include <stdio.h>
#include <stdlib.h>

template <typename T, int N>
struct array {
    array<T,N>() : data(NULL), offset((int*) malloc(sizeof(int)*N)){}
    array<T,N>(T *data, int *offset) : data(data), offset(offset){}
    array<T,N-1> operator[](int i){return array<T,N-1>(&data[i*offset[N]], offset);}
    bool resize(int *size){
        offset[N-1] = 1;
        int total_size = size[N-1];
        for(int i = N-2; i >= 0; i--){
            total_size *= size[i];
            offset[i] = offset[i+1]*size[i+1];
        }
        return (data = (T*) realloc (data, total_size*sizeof(T)));
    }
    T *data;
    int *offset;
};

template <typename T>
struct array<T,1>{
    array<T,1>(T *data, int *offset) : data(data){}
    T& operator[](int i){return data[i];}
    T *data;
};

int main () {
    array<int, 4> a;

    // create array with dimensions [1][3][3][7]
    int size[4] = { 1, 3, 3, 7 };
    a.resize(size);               

    a[0][1][2][3] = 123;

    return 0;
}

享受。

N-dimensional arrays of arbitrary type and size in C++:

This answer is inspired by the answer of Pavel Radzivilovsky, thanks for that. I had a bit of a hard time realizing the implementation, as it was my first stab at recursive templates. I'd like to share what I have done such that others can understand more quickly than I did.

I have written a c++ template class to create a n-dimensional array of arbitrary type and size. It needs to be instantiated with the array type and the number of dimensions. The size can be changed dynamically. I've given below a bare (stripped) working version of how to create a multidimensional array of which the elements can be accessed through successive application of the operator[] (e.g. array[x][y][z]). This version can only handle arrays of dimension n>1. The main function shows how to create a 4-dimensional array of integers as an example.

EDIT: keep in mind that the example below is minimal for readability, in that it does not deallocate the array, nor does it do bounds checking on access. Adding this is trivial, and left to the programmer.

#include <stdio.h>
#include <stdlib.h>

template <typename T, int N>
struct array {
    array<T,N>() : data(NULL), offset((int*) malloc(sizeof(int)*N)){}
    array<T,N>(T *data, int *offset) : data(data), offset(offset){}
    array<T,N-1> operator[](int i){return array<T,N-1>(&data[i*offset[N]], offset);}
    bool resize(int *size){
        offset[N-1] = 1;
        int total_size = size[N-1];
        for(int i = N-2; i >= 0; i--){
            total_size *= size[i];
            offset[i] = offset[i+1]*size[i+1];
        }
        return (data = (T*) realloc (data, total_size*sizeof(T)));
    }
    T *data;
    int *offset;
};

template <typename T>
struct array<T,1>{
    array<T,1>(T *data, int *offset) : data(data){}
    T& operator[](int i){return data[i];}
    T *data;
};

int main () {
    array<int, 4> a;

    // create array with dimensions [1][3][3][7]
    int size[4] = { 1, 3, 3, 7 };
    a.resize(size);               

    a[0][1][2][3] = 123;

    return 0;
}

Enjoy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文