Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ square bracket overloading with and without const/ampersand

I am writing C++ code, and ran into a case where I wish to overload the square bracket operator for my class. From various sources, I find that you usually make two methods to do this, one with the const keyword, and one without the const keyword, but with an ampersand (&) before the method name. An example is given below.

int MyClass::operator[](unsigned int i) const {
    return this->values[i];
}

int & MyClass::operator[](unsigned int i) {
    return this->values[i];
}

My questions are as follows:

  1. Why do I have two methods, one with the const keyword, and one without it?
  2. What does the ampersand (&) in my second method do?
  3. Why can I set a value at a given index using square brackets, when none of my methods are setters, and which of these two methods is invoked when I set a value?
like image 911
Henrik Hillestad Løvold Avatar asked Sep 13 '25 19:09

Henrik Hillestad Løvold


1 Answers

Why do I have two methods, one with the const keyword, and one without it?

The const keyword sets a constraint that prevents the function from modifying the object. For example, if you use the const keyword in a setter, you'll get a compiler error.

So the first function won't allow any modification on the object and in this case it will return a copy of the accessed element. The first function is a getter in disguise, it is a read only access, so to speak.

What does the ampersand (&) in my second method do?

The second function, instead, has the ampersand after the type, which means that it will return a reference of the returned value and not a copy of it. The returned value is part of the object, so returning a reference to it implies a potential modification and the const keyword wouldn't allow it.

So this second function is a setter in disguise, it is a write access.

Why can I set a value at a given index using square brackets, when none of my methods are setters, and which of these two methods is invoked when I set a value?

As we've seen, the second function acts like a setter. When you use it, the returned value is a reference to the real element inside your object, and is valid for assignation (we call it a lvalue, more about them here).

The point of this overload is: whenever you use the operators for a read operation (right side of the assignation or as a parameter) the first function will be called. If you use it for a write operation, it will be the second. In fact, this is how the same operator works for the STL containers you are probably using in your code.

like image 121
Miguel Avatar answered Sep 15 '25 09:09

Miguel