I've been teaching a C++ programming class for many years now and one of the trickiest things to explain to students is const overloading. I commonly use the example of a vector-like class and its operator[]
function:
template <typename T> class Vector { public: T& operator[] (size_t index); const T& operator[] (size_t index) const; };
I have little to no trouble explaining why it is that two versions of the operator[]
function are needed, but in trying to explain how to unify the two implementations together I often find myself wasting a lot of time with language arcana. The problem is that the only good, reliable way that I know how to implement one of these functions in terms of the other is with the const_cast
/static_cast
trick:
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]); }
The problem with this setup is that it's extremely tricky to explain and not at all intuitively obvious. When you explain it as "cast to const, then call the const version, then strip off constness" it's a little easier to understand, but the actual syntax is frightening,. Explaining what const_cast
is, why it's appropriate here, and why it's almost universally inappropriate elsewhere usually takes me five to ten minutes of lecture time, and making sense of this whole expression often requires more effort than the difference between const T*
and T* const
. I feel that students need to know about const-overloading and how to do it without needlessly duplicating the code in the two functions, but this trick seems a bit excessive in an introductory C++ programming course.
My question is this - is there a simpler way to implement const
-overloaded functions in terms of one another? Or is there a simpler way of explaining this existing trick to students?
I usually consider this to be a language restriction, and advise people that -- unless they really know what they're doing -- they should just reimplement. In the vast majority of cases, these functions are simple one-line getters, so there's no pain.
In your capacity of teaching C++ I would feel even more strongly about this approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With