TOptional::Get may return dangling reference

The prototype of TOptional::Get is

	/** @return The optional value when set; DefaultValue otherwise. */
	const OptionalType& Get(const OptionalType& DefaultValue) const { return IsSet() ? *(OptionalType*)&Value : DefaultValue; }

If the DefaultValue is a temporary object, it is destroyed after the Get function return.

struct Foo {
    int value;
    Foo(int n) : value(n) {}
    ~Foo() { value = -1; }
};

TOptional<Foo> OptFoo;
const auto& foo  = OptFoo.Get(1);

foo.value is -1 because DefaultValue is constructed with the value 1, but it is destructed after the Get returns.

This kind of bug is especially hard to find for FString or container types.

The counterpart in std::optional is value_or, it returns a value:

template< class U > constexpr T value_or( U&& default_value ) const&;
template< class U > constexpr T value_or( U&& default_value ) &&;

See std::optional<T>::value_or - cppreference.com

1 Like