My class' interface includes an accessor to an object which may not exist. Currently, it returns a pointer which may be null. I would like to replace the pointer with std::optional
as suggested here. The accessor has a const
overload which uses Meyers' const_cast trick to avoid repeating the same code twice.
In short, I want to replace this:
T const * MyClass::get() const {
/* non-trivial */
}
T * MyClass::get() {
return const_cast<T *>(const_cast<MyClass const *>(this)->get());
}
with this:
std::optional<T const &> MyClass::get() const {
/* non-trivial */
}
std::optional<T &> MyClass::get() {
auto t = const_cast<MyClass const *>(this)->get();
return t ? std::optional<T &>(const_cast<T &>(* t)) : std::nullopt;
}
The replacement seems unsatisfactory because:
- it introduces a branch;
- the additional complexity somewhat defeats the goal of making the overload be lightweight (and trivially optimized away by the compiler).
I am assuming that the std::optional
specialization for a reference can basically boil down to little more than a pointer with added safety and wonder therefore if there's some way to preserve the simplicity of the pointer solution. Is there a more satisfactory way to write the accessor overload to use std::optional
?