Is it guaranteed to be safe by the C++ standard to derive a pointer to T from std::aligned_storage_t<sizeof(T), alignof(T)> before the T itself is actually created? For example, is the following legal?
std::aligned_storage_t<sizeof(T), alignof(T)> storage;
T* ptr = reinterpret_cast<T*>(&storage); // Perhaps with std::launder?
new (&storage) T;
ptr->DoSomething();
I would appreciate references to the standard about why this is allowed/not allowed. I'm writing in C++17, but would still be interested if the answer is different in C++20.
The reason I want this to be legal is to efficiently implement a pair of promise/future types, with covariance in the value type (so Future<Animal> can be constructed from Promise<Cat>). Here is a sketch of what that might look like, with all the SFINAE and synchronization and other details stripped:
template <typename T>
class Promise {
private:
// The storage in which we'll eventually construct our object once SetValue
// is called. We don't just use a T object directly because we don't want
// to require it to be default-constructible.
std::aligned_storage_t<sizeof(T), alignof(T)> storage_;
// Does storage_ contain a value yet?
bool ready_ = false;
public:
void SetValue(T value) {
new (&storage_) T(std::move(value));
ready_ = true;
}
};
template <typename T>
class Future {
private:
// A pointer that will eventually be valid.
const T* const ptr_;
public:
// Create a future that can be used to access the value set on the supplied
// promise.
//
// REQUIRES: U is T, or a subclass of T.
template <typename U>
Future(Promise<U>* promise)
: ptr_(reinterpret_cast<U>(promise->storage_)) {}
// REQUIRES: Promise::SetValue has been called.
const T& Get() const { return *ptr_; }
}