Здравствуйте. Хотел бы услышать сторонние мнения на мою проблему и способ её решения.
Итак, нужно как-то хранить в памяти такую вещь:
struct sItem{
char Name[25];
int ChildCount;
int Size;
void* Value;
};
vector<sItem> Item;
Задумка такова: в зависимости от Size присваивается тип Value.
1 –char
2 – short
4 – int
более – char[Size]
(то что строка занимает минимум 5 байт сочтем за издержки).
Меня сильно смущают все эти void*. В связи с этим вопрос: как еще можно реализовать массив структур, где один элемент может быть разных типов.
Здравствуйте, Анатолий Широков, Вы писали:
АШ>http://www.boost.org/doc/html/any.html
А массив классов не слишком много будет есть памяти?
АШ>>http://www.boost.org/doc/html/any.html
MH>А массив классов не слишком много будет есть памяти?
1) еще есть
http://www.boost.org/doc/html/variant.html
2) памяти будет использоваться точно меньше, чем твой велосипед; насколько мне известно any выделяет память под объект динамически, variant использует max(список_типов) байт памяти
3) можно немного сжать твою структуру если использовать union:
enum {
TYPE_CHAR25,
TYPE_CHILDCOUNT,
TYPE_VALUE
};
struct sItem{
union {
char Name[25];
int ChildCount;
void* Value;
};
int type;
sItem &operator =(int arg) {
Value = arg;
type = TYPE_VALUE;
return *this;
}
};
p.s. сразу скажу что не-POD типы в union запихнуть нельзя.
Здравствуйте, MoreHate, Вы писали:
MH>Здравствуйте. Хотел бы услышать сторонние мнения на мою проблему и способ её решения.
MH>Задумка такова: в зависимости от Size присваивается тип Value.
MH>1 –char
MH>2 – short
MH>4 – int
MH>более – char[Size]
MH>(то что строка занимает минимум 5 байт сочтем за издержки).
MH>Меня сильно смущают все эти void*. В связи с этим вопрос: как еще можно реализовать массив структур, где один элемент может быть разных типов.
где и как планируется реализовать выбор соответствующего типа? судя по всему во время заполнения полей структуры, т.к. конструктора у тебя нет. При этом существует потенциальная опасность, что Size и тип Value не будут соответствовать друг другу. Лучше эту задачу возложить на компилятор.
Для создания массива таких структур можно использовать тот же boost::any
#include <vector>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/any.hpp>
namespace mpl = boost::mpl;
template <int Size>
struct sItem
{
char Name[25];
int ChildCount;
typename mpl::if_<mpl::bool_<Size == 1>, char,
typename mpl::if_<mpl::bool_<Size == 2>, short,
typename mpl::if_<mpl::bool_<Size == 4>, int,
typename mpl::if_<mpl::bool_<Size >= 5>, char[Size], void>::type>::type>::type>::type Value;
};
typedef std::vector<boost::any> ItemsVector;
int main()
{
ItemsVector v;
v.push_back(sItem<1>());
v.push_back(sItem<2>());
v.push_back(sItem<5>());
//v.push_back(sItem<-1>()); error: 'Value' : illegal use of type 'void'
return 0;
}
т.к. нельзя создавать переменные типа void, компилятор сам ударит по рукам в случае, если параметр шаблона не будет лежать в множестве допустимых значений
Здравствуйте, MoreHate, Вы писали:
MH>Здравствуйте. Хотел бы услышать сторонние мнения на мою проблему и способ её решения.
MH>Итак, нужно как-то хранить в памяти такую вещь:
MH>MH>struct sItem{
MH> char Name[25];
MH> int ChildCount;
MH> int Size;
MH> void* Value;
MH>};
MH>vector<sItem> Item;
MH>
MH>Задумка такова: в зависимости от Size присваивается тип Value.
MH>1 –char
MH>2 – short
MH>4 – int
MH>более – char[Size]
MH>(то что строка занимает минимум 5 байт сочтем за издержки).
MH>Меня сильно смущают все эти void*. В связи с этим вопрос: как еще можно реализовать массив структур, где один элемент может быть разных типов.
Если не в ладах с boost`ом или вообще с шаблонами, то как вариант объяви базовый класс с необходимыми виртульными методами и переопределяй как хочешь...
class BaseClass
{
public:
virtual char *GetString(){return NULL;}
};
class IntClass : public BaseClass
{
int mInt;
public:
IntClass(int intVal){mInt=intVal;}
};
class CharSizeClass : public BaseClass
{
int mCharSize;
char *mCharVal;
public:
CharSizeClass(char *charVal,int size){mCharSize=size; mCharVal=charVal;}
char *GetString(){return mCharVal;}
};