I stumbled upon an implemenation of Optional<T>
which is based on LLVM's Optional.h class and couldn't quite figure out why it is implemented the way it is.
To keep it short, I'm only pasting the parts I don't understand:
template <typename T>
class Optional
{
private:
inline void* getstg() const { return const_cast<void*>(reinterpret_cast<const void*>(&_stg)); }
typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type storage_type;
storage_type _stg;
bool _hasValue;
public:
Optional(const T &y) : _hasValue(true)
{
new (getstg()) T(y);
}
T* Get() { return reinterpret_cast<T*>(getstg()); }
}
And the most naive implementation I could think of:
template <typename T>
class NaiveOptional
{
private:
T* _value;
bool _hasValue;
public:
NaiveOptional(const T &y) : _hasValue(true), _value(new T(y))
{
}
T* Get() { return _value; }
}
Questions:
storage_type
? what was the author's intention?new (getstg()) T(y);
? Optional<T>
class have over NaiveOptional<T>
) ?The short answer is "performance".
Longer answer:
storage_type
provides an in-memory region that is (a) big enough to fit the type T and (b) is aligned properly for type T. Unaligned memory access is slower. See also the doc. new (getstg()) T(y)
is a placement new. It does not allocate memory, but instead it constructs an object in memory region passed to it. The doc (on all forms of new
- search for the "placement new").Optional<T>
implementation does not use dynamic memory allocation (see the point above).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With