
Using optional does not imply any overhead. You simply provide a specialization for optional<observer<T>>. You make optional<observer<T>> a friend of observer<T>, and create a private constructor that acts as the back door to allow your type to store a nullptr inside it to represent the empty state. Then the only way to get in this state is through optional, so users of the type never see that such a state is possible. The behavior of operator< is a little trickier. That being said, I do not believe that this type should have operator<. This type is not usable as an iterator, which is the only situation where operator< makes sense for pointer types. Instead, I would just specialize std::less (which I see you delegate to in your operator<) to allow use in std::map. Then the question of the performance of optional's operator< goes away, because it is not defined.