It is like std::optional
, but doesn't store an extra bool. User has to make sure to access only after initializing.
template<class T>
union FakeOptional { //Could be a normal struct in which case will need std::aligned storage object.
FakeOptional(){} //Does not construct T
template<class... Args>
void emplace(Args&&... args){
new(&t) T{std::forward<Args&&>(args)...};
}
void reset(){
t.~T();
}
operator bool() const {
return true;
}
constexpr const T* operator->() const {
return std::launder(&t);
}
constexpr T* operator->() {
return std::launder(&t);
}
T t;
};
If you are wondering why I need such an obscure datastructure, check here: https://gitlab.com/balki/linkedlist/tree/master
Question
std::launder
? I guess not.std::launder
is available only in c++17, how to implement above class in c++14? boost::optional
and std::experimental::optional
should have needed similar feature or did they use compiler specific magic?Note: It is easy to miss, the type is declared as union
. Which means constructor of T
is really not called. Ref: https://gcc.godbolt.org/z/EVpfSN
No, you can't. One of the reasons that std::launder
is proposed is that std::optional
is not implementable in C++14. You can refer to this discussion for detail.
On the other hand, you can implement one without constexpr
. The idea is to use a buffer with reinterpret_cast
because the result of reinterpret_cast
will always refer to the newly created object (in C++17 std::launder
is still required but in C++14 this is fine). For example,
template<class T>
struct FakeOptional {
FakeOptional(){}
template<class... Args>
void emplace(Args&&... args){
new(&storage) T{std::forward<Args&&>(args)...};
}
void reset(){
reinterpret_cast<T*>(&storage)->~T();
}
operator bool() const {
return true;
}
const T* operator->() const {
return reinterpret_cast<const T*>(&storage);
}
T* operator->() {
return reinterpret_cast<T*>(&storage);
}
std::aligned_storage_t<sizeof(T), alignof(T)> storage;
};
The implementation of boost::optional
uses this idea and does not implement constexpr
semantic (you can refer to its source code for details).
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