Std :: optional and polymorphism

I read the article "Stack Overflow" in many posts, when using a pointer (for an argument or return value) and nullptr (which makes it optional), it is usually better to use std::optional .

However, what if the pointer is a polymorphic type? Best to use std::optional or a pointer?

+6
source share
4 answers

optional does not work with polymorphic types. This is a value type, and polymorphic base classes do not work in optional . Just like putting polymorphic base classes in vector or similar containers doesn't work.

Returns a pointer. There is a reason why advice is usually indicated as "generally."

+5
source

The std::optional clause explicitly says that it is not polymorphic:

value_ptr requires the selected object to be allocated to the free store. This means that sizeof(value_ptr<T>) fixed regardless of T value_ptr is "polymorphic": an object of type value_ptr<T> can point to an object of type DT obtained from T Deep copy preserves the dynamic type. does not necessarily require free distribution of stores: its creation is more efficient; it is not "Polymorphic."

Your options unique_ptr down to a raw pointer or unique_ptr . Use unique_ptr if you need a copy and a raw pointer otherwise.

+2
source

You can write polymorphic pseudo-optional.

You want to implement a small optimization of objects with a limited object size / alignment (possibly parameters) and include a base class plus a set of additional operations for erasing to (for example, copying or moving). I wrote a limited polymorphic type without a backup copy of a pointer that simply could not be compiled if it ran out of space for the same reason, probably placed somewhere on SO.

Optional is not polymorphic, but can be regular and pseudoregular value types. Most arguments for optional / smart ptrs pointers are actually arguments for using regular and pseudo-regular non-allocating types.

+2
source

" I read about stackoverflow in many posts that when using a pointer (for an argument or return value) and nullptr (which makes it optional), it is generally better to use std::optional .

Presumably, you mean using std::optional to wrap a value other than a pointer or reference. In this case, you are talking about an optional argument or an optional return value .


Using optional for an optional argument has the disadvantage that the object is being copied, or at least moved, which may be undesirable. In addition, this eliminates polymorphism.

The easiest way to do this, which also avoids unnecessary copying and supports polymorphism, is to use a pointer to const :

 void foo( Some_type const* p_object ) 

But then the caller will need to use the & operator for the actual argument.

To simplify calls, you can provide overload as syntactic sugar:

 void foo() { foo( nullptr ); } void foo( Some_type const& object ) { foo( &object ); } 

which supports type calls

 foo(); 

and

 foo( o ); 

Using optional for the return value has the advantage that a throw exception can be avoided when the calling code correctly checks for the value. But it apparently excludes the usual RVO (return value optimization) for the wrapped object - the affectionate word β€œappears” because I cannot see this harmless proof of this, but still I do not see how RVO can be done. Therefore, when a case without a return value is rare, and / or efficiency is very important, it is best to simply 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 so as not to indicate the return value.

For a polymorphic optional return value, you can use a smart pointer such as std::unique_ptr or std::shared_ptr , which handles ownership.

+1
source

All Articles