Цель контейнера
Я создаю контейнер, который предназначен для хранения отсортированных целочисленных значений без знака очень эффективным образом в ОЗУ.Идея состоит в том, чтобы сгруппировать значения по общему основанию.Вместо
std::vector<unsigned int> V = {1234,1254,1264,1265,1267,1268,1271,1819,1832,1856,
1867,1892,3210,3214,3256,3289};
у меня будет что-то вроде
MyContainer V =
{
{12..
..34, ..54, ..64, ..65, ..67, ..68, ..71
},
{18..
..19, ..32, ..56, ..67, ..92
}
{32..
..10, ..14, ..56, ..89
}
};
. В приведенном выше примере я сгруппировал значения по блокам по 100. Было бы более логично сгруппироватьданные по группе 2 ^ 16.Предполагая, что каждый unsigned int
равен 4 байта, а каждый unsigned short
равен 2 байта, первый вектор из 16 элементов будет занимать не менее 16 * 4 = 64 байта, а второй вектор будет занимать 19 * 2 = 38 байтов ОЗУ.
Краткое описание контейнера
Вкратце, вот организация этого контейнера ...
class MyContainer
{
// attribute
std::vector<Block> data;
// methods
// ..
};
class Block
{
// attributes
unsigned short radix;
std::vector<unsigned short> suffixs; // contains all the suffix associated with this radix
// methods
// ..
};
Хотя совет по поводу этой структуры данных будет приветствоваться, ядроМой вопрос о реализации итератора.
Итератор
У меня возникли проблемы при создании итератора.Мой итератор должен также разрешить прямое исследование и произвольный доступ.Я впервые создаю классический шаблон проектирования итераторов, и, скорее всего, я делаю ошибки.Вот атрибуты моего итератора
class Iterator
{
// attributes
std::vector<Block>::iterator bigP; // points to a Block
std::vector<unsigned short>::iterator smallP; // points to an unsigned int within the Block pointed by bigP
std::vector<Block>::iterator bigPEnd;
// methods
// ...
};
Q1: должен ли MyContainer::iterator
содержать итераторы (как это в настоящее время имеет место) или он должен содержать указатели?Почему?
Я думал, что когда итератор указывает на последний unsigned int
из Block
, тогда operator++()
должен толкнуть bigP
к следующему Block
и нажать smallP
к первому элементу
Мне кажется неправильным, что я должен включить итератор в data.end () (называемый bigPEnd
), но в итоге я добавил его, когда понял, что когдаoperator++()
вызывается, в то время как MyContainer::iterator
указывает на последние unsigned int
из последних Block
, я должен был знать, что не могу установить smallP
на bigP->begin()
, так как это приведет к ошибке сегментации как*bigP
не существует.
Q2: мне нужен указатель на последний элемент data
?Как этого избежать?
Я также сталкиваюсь с аналогичной проблемой при создании MyContainer::iterator
для пустого вектора.Обычно я создаю итератор с
MyContainer::iterator MyContainer::begin()
{
return iterator(data.begin(), data.front().suffixs.begin(), data.end());
// ^^ ^^ ^^
// bigP smallP bigPEnd
}
Однако data.front()
приведет к ошибке сегментации, когда data
пусто.Если бы я использовал указатели, я мог бы установить smallP
на nullptr
, когда данные пусты и когда bigP == data.end()
независимо от того, пустые данные или нет.
Q3: Как я могу справиться с smallP
когда не на что указывать?
Не могли бы вы дать мне несколько советов по реализации этого итератора?