سؤال

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:

  1. it introduces a branch;
  2. 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?

هل كانت مفيدة؟

المحلول

As mentioned by others, instantiating std::optional with reference type is ill-formed in the c++14 standard. (See N3690 20.6.2.) Thus using std::optional as a drop-in replacement for a pointer (that points to a single object whose absence is represented by a value of nullptr) is not viable unless you are willing to copy the object by value, rather than by reference.

However, the specification leaves the door open to adding such functionality in the future. Additionally, section 7.15 of N3672 suggests a workaround using std::reference_wrapper.

Update: Additionally, @HowardHinnant informs me that inclusion in the standard has been punted out of c++14 altogether.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top