I would like to implement a Scala-like Option / Haskell-like Maybe class in C++. For efficiency reasons, I do not want to use dynamically allocated memory, nor do I want to use polymorphism. In addition, I do not want any object of the embedded type to be created if the Option is None.
Can anybody tell me whether the following approach may cause problems? I have to statically allocate memory for the embedded object within my Option class, but I cannot define a member field of the embedded type, since this would be initialized on creation of the Option object even if the Option is None.
template <typename T>
class Option {
private:
uint8_t _storage [sizeof (T)];
T * _embedded;
public:
Option () : _embedded (nullptr) {
}
Option (const T & obj) : _embedded (new (_storage) T (obj)) {
}
Option (const Option<T> & other)
: _embedded (
other->_embedded ? new (_storage) T (other->_embedded) : nullptr
) {
}
// ...
~Option () {
if (_embedded) _embedded->~T ();
}
};
I don't think that the array is required to be aligned the same way the object class may require. In practice I wouldn't expect any problems unless the type has funny alignment requirements.
With C++ 2011 you could use a union
to hold the actual representation, although you'd still need to manage the held object’s life-time. There is a boost::optional<T>
and a proposal to add a similar type to the next revision of the standard.
For me this looks fine, except for:
uint8_t _storage [sizeof(T)/sizeof(uint8_t)];
Option (const Option & other)
: _embedded (other->_embedded ? new (_storage)T(other->_embedded) : nullptr)
{
}
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