A simple way for what you want is:
enum datatype
{
dt_none,
dt_char,
dt_uchar,
dt_short,
dt_ushort,
dt_long,
dt_ulong,
dt_float,
dt_double
};
struct Any
{
datatype type; // To know what is stored inside union, not mandatory if you know that in another way
union
{
char vchar;
unsigned char vuchar;
short vshort;
unsigned short vushort;
long vlong;
unsigned long vulong;
float vfloat;
double vdouble;
} data;
};
std::vector<Any> mydata;
You can avoid using an union, but it take more memory (pointer for every value + real size) and it's more complicated to use:
struct Any
{
private:
void * data;
datatype type;
public:
Any():
data(NULL),
type(dt_none)
{}
~Any()
{
deleteData();
}
void deleteData()
{
// Because deleting a void * is UB, we have to check real datatype
if (data != NULL)
{
if (type == dt_char)
delete static_cast<char *>(data);
if (type == dt_uchar)
delete static_cast<unsigned char *>(data);
....
}
}
datatype getType() const
{
return type;
}
void setChar(char v)
{
deleteData();
data = new char(v);
type = dt_char;
}
char toChar() const
{
return *static_cast<char *>(data);
}
.....
void setDouble(double v)
{
deleteData();
data = new double(v);
}
double toDouble() const
{
return *static_cast<double*>(data);
}
};
A possible optimization, is using pointer to store small type data, to save some bytes (but do it carefully!). But if you store a lot of big type data, union
still better. Also, size of a pointer is platform dependent, so it's difficult to choose which type can be store directly in pointer and have a portable code. Also, on 64bits computer, size of pointer is 8 bytes, which is also common size of double
(so, is this case, store directly every type inside pointer, which is same memory consumption than union
but in a really more complicated and unsecure way ):
struct Any
{
private:
void * data;
datatype type;
public:
Any():
data(NULL),
type(dt_none)
{}
~Any()
{
deleteData();
}
void deleteData()
{
// Because deleting a void * is UB, we have to check real datatype
if (type != dt_char && type != dt_uchar && data != NULL)
{
if (type == dt_double)
delete static_cast<double *>(data);
....
}
data = NULL;
}
datatype getType() const
{
return type;
}
void setChar(char v)
{
data = reinterpret_cast<void *>(v);
}
char toChar() const
{
return static_cast<char>(reinterpret_cast<intptr_t>(data));
}
.....
void setDouble(double v)
{
deleteData();
data = new double(v);
}
double toDouble() const
{
return *static_cast<double*>(data);
}
};
All that to say you have only 2 simple solutions in your case (IMHO):
- if you really want to save memory, your have to use a vector per type.
- or use
union
PS: You can also take a look at third party library like boost::any
.