template <typename StoredT>
class InternalObject {
public:
using RefCountT = unsigned short;
template <typename... CtorTs>
static void* emplace(CtorTs&&...);
Types type;
RefCountT reference_count;
bool is_immovable;
StoredT stored_value;
InternalObject();
InternalObject(StoredT);
~InternalObject();
};
My class has a member StoredT stored_value
which I would like to be able to construct using emplace
and return a void*
to it.
However, if I want to do this, I would have to do InternalObject<StoredT> *io_ptr = new InternalObject<StoredT>;
which would force me to default-construct stored_value
.
The solution I attempted was to allocate the appropriate amount of space as an array of unsigned char
(the returned pointer is a heap pointer). Then, I tried to increment the pointer by appropriate amounts and modify the value there.
A more reproducible & complete example which does not produce a valid (non-POD) value for two
.
#include <iostream>
#include <vector>
struct S {
int one;
std::vector<int> two;
};
int main() {
unsigned char *s_ptr = new unsigned char[sizeof(S)];
S *s = reinterpret_cast<S*>(s_ptr);
*s_ptr = 100; // Fine
std::vector<int> *vec_ptr = reinterpret_cast<std::vector<int>*>(s_ptr + sizeof(int));
*vec_ptr = {5,6,7};
std::cout << s->two.capacity() << "\n"; // big ol' number
return 0;
}
Consider using std::optional<StoredT>
, which will allow you to defer the construction of the StoredT
that you want to hold:
#include <optional>
template <typename StoredT>
class InternalObject {
public:
using RefCountT = unsigned short;
template <typename... CtorTs>
void emplace(CtorTs&&... args) {
stored_value.emplace(args...);
}
Types type;
RefCountT reference_count;
bool is_immovable;
std::optional<StoredT> stored_value;
InternalObject();
InternalObject(StoredT);
~InternalObject();
};