McLovin
McLovin

Reputation: 3417

Multiple operator[] overloads

Take a look at this simple array class

class Array {
    const unsigned int _size;
    int _array[100];

public:
    Array() : _size(100) {
        for(unsigned int i = 0; i < _size; i++)
            _array[i] = 0;
    }

    int& operator[](unsigned int index) {
        cout << "normal operator[].\n";
        return _array[index];
    }

    const int& operator[](unsigned int index) const {
        cout << "const operator[].\n";
        return _array[index];
    }
};

int main()
{
    Array a;

    a[3] = 1;
    cout << a[3] << "\n";

    system("pause");
    return 0;
}

The "normal operator[]" line is executed twice, though I would expect the second call (cout << a[3] << "\n";) to be using the const version of the overloaded operator, because it doesn't change the array itself.

Why is that? Is there a way to force the const version to be called as I wish?

Upvotes: 2

Views: 278

Answers (2)

Monfico
Monfico

Reputation: 154

When you have an overloaded const version of a method, the const version will be called when the object is const. For example:

#include <iostream>
using namespace std;

class MyClass
{
public:

    void foo()
    {
        cout << "foo()" << endl;
    }

    void foo() const
    {
        cout << "foo() const" << endl;
    }
};

int main()
{
    MyClass a;
    const MyClass b;

    a.foo();
    b.foo();

    return 0;
}

will call the normal foo() for the object a, and the const version for the object b.

In your case, you just have to avoid trying to assign to the const version. For example:

Array a;
const Array b;

a[3] = 1;
// b[3] = 1; // error
cout << a[3] << "\n";
cout << b[3] << "\n";

works fine. But if you try to make the assignment to b, you get a compile error.

Upvotes: 1

pmttavara
pmttavara

Reputation: 768

std::ostream &operator<<(int x) doesn't take its parameter as const (because const isn't useful when passing by value), so the non-const operator[] can be called.

So, when will const operator[] be called?

It is true that a const vector variable declaration is almost always useless aside from some edge cases. The primary reason const operator[] is important, and the most often you will see it used, is calling it on a reference parameter.

int readStuff(const std::vector<int> &dontMutateMe) {
    return dontMutateMe[42]; // const
}

Constant reference parameters are valuable, and this code wouldn't work without const operator[].

Upvotes: 0

Related Questions