4

Is it possible to define an overloaded operator[] that takes more than one argument? That is, can I define operator[] as follows:

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

and later use it like this?

double b=some_obj[7,3];
Dan
  • 12,157
  • 12
  • 50
  • 84

8 Answers8

7

No you can't overload operator[] to take more than one argument. Instead of

double b = some_obj[7,3];

use

double b = some_obj[7][3];

This answer explains how to create a proxy object to be able to the latter.

Otherwise, you could just overload operator() to take 2 arguments.

Community
  • 1
  • 1
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • 3
    Even better (in my opinion, at least): make a function "get", "at" or something like that, with two arguments. In most cases, it will make the code clearer than overloading operator (). – Andrea Bergia Aug 11 '11 at 21:29
6

No. The idiomatic way to do that in C++ is

double b = some_obj[7][3];
Andrea Bergia
  • 5,502
  • 1
  • 23
  • 38
  • 2
    Though that's not necessarily the best way, it requires somewhat awkward proxy classes if you do it properly. Depending on what you actually want it can be more straightforward to just use `operator()` with two arguments. – leftaroundabout Aug 11 '11 at 21:05
5

Prior to C++23 it isn't possible. You can do this from C++23.

From cppreference:

Since C++23, operator[] can take more than one subscripts. For example, an operator[] of a 3D array class declared as T& operator[](std::size_t x, std::size_t y, std::size_t z); can directly access the elements.

example code from there: 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)

Thus, the snippets you posted will work in C++23.

michuu
  • 315
  • 4
  • 10
  • good answer. I'm just curious why you chose not to edit an existing one, which would help people find the best information close together. currently, they'd need to to scroll to the bottom to find this. – starball Sep 05 '22 at 21:34
  • it's only last because of your sort and the voting. it's a good well formed answer that is DISTINCT from others and shouldnt be part of them – UpAndAdam Sep 05 '22 at 21:43
3

No, C++ syntax says that in

double b=some_obj[7,3];

the comma is the comma operator, not the comma that separates arguments.

john
  • 85,011
  • 4
  • 57
  • 81
2

You could do what Andrea suggested, or you could overload operator() to take two arguments:

// 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);
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
1

The better way to do that, since it doesn't lock you into creating temporaries and allows multiple arguments, is operator(). More details are in the C++ FAQ.

ChrisV
  • 3,363
  • 16
  • 19
1

Bottom line: No, don't confuse your users.

From C++ FAQ:

Remember the purpose of operator overloading: to reduce the cost and defect rate in code that uses your class. If you create operators that confuse your users (because they're cool, because they make the code faster, because you need to prove to yourself that you can do it; doesn't really matter why), you've violated the whole reason for using operator overloading in the first place.

0

You can't, but in this case I think a function would be better since it is not intuitive what your operator is doing.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625