Упрощение перегрузки констант?

Я уже много лет преподаю класс программирования C ++, и одна из самых сложных вещей, которые нужно объяснить студентам, - это перегрузка констант. Я обычно использую пример векторного класса и его функцию operator [] :

template <typename T> class Vector {
public:
    T& operator[] (size_t index);
    const T& operator[] (size_t index) const;
};

У меня практически нет проблем с объяснением, почему это две версии оператора [] необходимы, но, пытаясь объяснить, как объединить две реализации вместе, я часто трачу много времени на языковые арканы. Проблема в том, что единственное хорошее, Надежный способ, которым я знаю, как реализовать одну из этих функций с точки зрения другой, - это трюк const_cast / static_cast :

template <typename T> const T& Vector<T>::operator[] (size_t index) const {
     /* ... your implementation here ... */
}
template <typename T> T& Vector<T>::operator[] (size_t index) {
    return const_cast<T&>(static_cast<const Vector&>(*this)[index]);
}

Проблема с этой настройкой в ​​том, что она чрезвычайно сложна объяснять и вовсе не интуитивно очевидно. Когда вы объясняете это как «приведение к константе, затем вызовите версию с константой, затем отключите константу», это немного легче понять, но фактический синтаксис пугает. На объяснение того, что такое const_cast , почему он уместен здесь и почему он почти повсеместно неуместен в других местах, обычно занимает у меня от пяти до десяти минут лекции, а понимание всего этого выражения часто требует больше усилий, чем разница между const T * и T * const . Я считаю, что студенты должны знать о перегрузке констант и о том, как это сделать без ненужного дублирования кода в двух функциях, но этот трюк кажется немного излишним для вводного курса программирования на C ++.

Мой вопрос - есть ли более простой способ реализовать const -перегруженные функции в терминах друг друга? Или есть более простой способ объяснить учащимся этот существующий трюк?

42
задан the Tin Man 1 December 2012 в 23:19
поделиться