” I have read on stackoverflow in many posts, that when pointer is used(for argument or return value) and nullptr
is allowed(making it optional), it is generally better to use std::optional
instead.
Presumably you're referring to using std::optional
to carry a value other than pointer or reference. In which case you're talking about an optional in-argument or an optional return value.
Using optional
for optional in-argument has the disadvantage that the object is copied, or at least moved, which can be undesirable. Also, it precludes polymorphism.
The simplest way to do it, which also avoids unnecessary copying, and supports polymorphism, is to use a pointer to const
:
void foo( Some_type const* p_object )
But then a caller will have to use the &
operator on the actual argument.
To simplify calls you can provide overloads as syntactic sugaring:
void foo() { foo( nullptr ); }
void foo( Some_type const& object ) { foo( &object ); }
which supports calls like
foo();
and
foo( o );
Using optional
for a return value has the advantage that exception throwing can be avoided when the calling code checks properly for value presence. But it appears to preclude ordinary RVO (return value optimization) for the wrapped object – weasel word “appears” because I can't see an airtight proof of this, but still I can't see how RVO could be done. So when the case of no return value is rare, and/or efficiency is very important, it might be better to just throw an exception. C++ only supports (raw) pointers and references for polymorphic return values, and there is no difference in this respect between using optional
and throwing an exception to indicate no return value.
For a polymorphic optional return value you can use a smart pointer like std::unique_ptr
or std::shared_ptr
, that handles the ownership.