Нет, вы не можете.Одна из причин, по которой предлагается std::launder
, заключается в том, что std::optional
не может быть реализовано в C ++ 14.Вы можете обратиться к этому обсуждению для подробностей.
С другой стороны, вы можете реализовать один без constexpr
.Идея состоит в том, чтобы использовать буфер с reinterpret_cast
, потому что результат reinterpret_cast
всегда будет ссылаться на вновь созданный объект (в C ++ 17 std::launder
все еще требуется, но в C ++ 14 это нормально).Например,
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;
};
Реализация boost::optional
использует эту идею и не реализует семантику constexpr
(вы можете обратиться к ее исходному коду дляподробнее).