C++的运算符[]可以接受多个参数吗?

Can C++'s operator[] take more than one argument?

本文关键字:参数 运算符 C++      更新时间:2023-10-16

是否可以定义一个接受多个参数的重载operator[] ?也就是说,我可以这样定义operator[]:

  //In some class
  double operator[](const int a, const int b){
     return big_array[a+offset*b];}

,然后像这样使用?

double b=some_obj[7,3];

不能重载operator[]以获取多个参数。而不是

double b = some_obj[7,3];
使用

double b = some_obj[7][3];

这个答案解释了如何创建一个代理对象来实现后者。

否则,您可以重载operator()以接受2个参数。

No。在c++中惯用的方法是

double b = some_obj[7][3];

在c++ 23之前,这是不可能的。你可以从c++ 23开始做。

从cppreference

:

从c++ 23开始,操作符[]可以接受多个下标。例如,声明为T& operator[](std::size_t x, std::size_t y, std::size_t z);的3D数组类的操作符[]可以直接访问元素。

示例代码:https://godbolt.org/z/993s5dK7z

From c++ 23 draft:

struct X {
  Z operator[](std::initializer_list<int>);
  Z operator[](auto...);
};
X x;
x[{1,2,3}] = 7;                 // OK, meaning x.operator[]({1,2,3})
x[1,2,3] = 7;                   // OK, meaning x.operator[](1,2,3)

因此,您发布的代码片段将在c++ 23中工作。

不,c++语法说在

double b=some_obj[7,3];

逗号是逗号操作符,而不是分隔参数的逗号。

底线:不,不要混淆你的用户

选自c++ FAQ:

请记住操作符重载的目的:减少开销和使用您的类的代码中的缺陷率。如果你创建运算符迷惑你的用户(因为他们很酷,因为他们编写代码)更快,因为你需要向自己证明你可以做到;为什么并不重要),你已经违背了使用的全部理由操作符重载。

您可以按照Andrea的建议做,或者您可以重载operator()以接受两个参数:

// In some class
double operator()(const int a, const int b) {
    return big_array[a + offset * b];
}
// Then use it like this:
double b = some_obj(7, 3);

更好的方法是operator(),因为它不会将您锁定在创建临时变量并且允许多个参数。

你不能,但在这种情况下,我认为函数会更好,因为它不是直观的你的操作符在做什么。