Last time, we added the ability to create non-modifying tracking pointers, but it required that you start with a non-const trackable object. But what if you want to create a non-modifying tracking pointer to an object to which you have only a const reference?
It took me a few tries before I hit upon the simple solution.¹
We just need to make the trackable object’s m_trackers
mutable, and then patch up the consequences.
template<typename T> struct trackable_object { ⟦ ... ⟧ tracking_ptr<T> track() noexcept { return { owner() }; } tracking_ptr<const T> track() const noexcept { return { owner() }; } tracking_ptr<const T> ctrack() const noexcept { return { owner() }; } private: friend struct tracking_ptr_base<T>; T* owner() const noexcept { return const_cast<T*>(static_cast<const T*>(this)); } tracking_node mutable m_trackers; ⟦ ... ⟧ };
After making the m_trackers
mutable, we can make the ctrack()
method const
. We may as well also add a track() const
that produces a read-only tracker from a const object. This is analogous to how C++ standard library container begin()
and and end()
methods produce read-only iterators if obtained from const containers.
Casting away const when creating and updating the tracking_ptr<const T>
is okay because the tracking_ptr<const T>
‘s get()
method will reapply const before giving it to the client, and the only other use of the pointer is to access the m_trackers
, which is now mutable.
There’s still a problem: Although you can convert a T*
to a const T*
, a std::
to a std::
, and a std::
to a std::
, you cannot convert a tracking_ptr<T>
to a tracking_ptr<const T>
. We’ll fix that next time.
Bonus chatter: I considered whether I should also support tracking_ptr<volatile T>
and tracking_ptr<const volatile T>
. It wouldn’t be hard, but it would be extra typing. I decided not to, on the grounds that the C++ standard library typically doesn’t bother with volatile
either: Standard containers have begin()
and cbegin()
but not vbegin()
or cvbegin()
.
¹ As Blaise Pascal is reported to have written, “If I had more time, I would have written a shorter letter.” Sometimes it takes a lot of work to come up with what ends up looking easy.
0 comments
Be the first to start the discussion.