Я преподаю программирование на C++ уже много лет, и одна из самых сложных вещей, которую нужно объяснить студентам, — это перегрузка констант. Я обычно использую пример векторного класса и его функцииoperator[]:
Код: Выделить всё
template class Vector {
public:
T& operator[] (size_t index);
const T& operator[] (size_t index) const;
};
У меня практически нет проблем объяснить, почему необходимы две версии функцииoperator[], но, пытаясь объяснить, как объединить две реализации вместе, я часто теряю много времени на языковые загадки. Проблема в том, что единственный известный мне хороший и надежный способ реализовать одну из этих функций в терминах другой — это const_cast/
трюк:
Код: Выделить всё
template const T& Vector::operator[] (size_t index) const {
/* ... your implementation here ... */
}
template T& Vector::operator[] (size_t index) {
return const_cast(static_cast(*this)[index]);
}
Проблема этой настройки в том, что ее чрезвычайно сложно объяснить и она совсем не очевидна интуитивно. Когда вы объясняете это как «привести к const, затем вызвать константную версию, а затем убрать константность», это немного легче понять, но реальный синтаксис пугает. Объяснение того, что такое const_cast, почему оно уместно здесь и почему оно почти всегда неуместно в других местах, обычно занимает у меня пять-десять минут лекционного времени, а понимание всего этого выражения часто требует больше усилий, чем разница между const T* и T* const. Я чувствую, что студентам необходимо знать о перегрузке const и о том, как это сделать без ненужного дублирования кода в двух функциях, но этот трюк кажется немного чрезмерным для вводного курса программирования на C++.
Мой вопрос заключается в следующем: существует ли более простой способ реализовать перегруженные const функции с точки зрения друг друга? Или есть более простой способ объяснить студентам этот существующий трюк?
Подробнее здесь:
https://stackoverflow.com/questions/458 ... verloading