Using optional does not imply any overhead. You simply provide a
specialization for optional. You make optional 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.