Перегрузка оператора Const и Non-Const

У меня есть тема, в которой я смущен тем, что мне нужно проработать. Перегрузка оператора с помощью версии const и неконстантной версии.

// non-const
double &operator[](int idx) {
    if (idx < length && idx >= 0) {
        return data[idx];
    }
    throw BoundsError();
}

Я понимаю, что эта функциональная часть класса, принимает индекс и проверяет его логический, возвращает индекс данных массива в классе. Там также функция с одним и тем же телом, но с вызовом функции как

const double &operator[](int idx) const

Почему нам нужна две версии?

Этот примерный вопрос также может помочь в разработке. Какая версия используется в каждом случае ниже?

Array a(3);
a[0] = 2.0;
a[1] = 3.3;
a[2] = a[0] + a[1];

Моя гипотеза о том, что версия const вызывается только a[2], потому что мы не хотим рисковать модификацией a[0] или a[1].

Спасибо за любую помощь.

Ответ 1

Когда доступны обе версии, логика довольно проста: const версия вызывается для объектов const, версия non const вызывается для объектов const. Это все.

В вашем примере кода a находится объект const, что означает, что во всех случаях вызывается версия const. Версия const никогда не вызывается в вашем примере.

Точка наличия двух версий заключается в реализации доступа "читать/писать" для объектов const и только "читать" доступ для объектов const. Для const вызывается объект const версия operator [], которая возвращает ссылку const double &. Вы можете читать данные через эту константную ссылку, но вы не можете ее прописать.