2016-06-02 5 views
2

Здесь у меня есть простой контейнер multi_index, и мне интересно, есть ли какой-либо способ заставить multi_index распределять элементы смежно в памяти. Я думал, что это будет возможно, если основным индексом является random_access.Можно ли использовать контейнер multi_index для непрерывной памяти?

Однако этот простой пример показывает, что неожиданно элементы не смежны в памяти. Есть ли комбинация boost::multi_index::indexed_by, которая, вероятно, приведет к непрерывной памяти?

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/member.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/random_access_index.hpp> 

int main(){ 
    typedef boost::multi_index_container< 
     double, // simply store doubles 
     boost::multi_index::indexed_by< 
      boost::multi_index::random_access<> 
     > 
    > random_access_container; 

    random_access_container v; // fill container 
    v.reserve(10); // also tried this 
    v.push_back(1.); 
    v.push_back(2.); 
    v.push_back(3.); 

    assert(v[0] == 1.); // ok 
    assert(*(&v[0] + 1) == v[1]); // this fails, memory is not contiguous 
} 

Примечание 1: Я хочу, чтобы это для совместимости (так что я могу воспользоваться multi_index контейнера --with другого доступом options--), но и использовать прямой доступ к памяти (как можно с std::vector).

ПРИМЕЧАНИЕ 2: Я только что нашел эту цитату из документации, http://www.boost.org/doc/libs/1_61_0/libs/multi_index/doc/reference/rnd_indices.html#rnd_indices, поэтому она выглядит сложной.

За исключением особо оговоренных случаев, или если соответствующий интерфейс не существует, индексы произвольного доступа проверить те же требования, как контейнер станд :: вектор плюс требования к станд :: список определенного списка операции на [list.ops ]. Некоторые из наиболее важных отличий с относительно STD :: вектор являются: индексы

  1. Случайных доступа не обеспечивают неразрывность памяти, и, следовательно, не имеют функций-членов данных.

    ...

ответ

2

Нет, у вас нет примыкание памяти. Компоновка индекса случайного доступа, сродни boost::container::stable_vector:

random-access index memory layout

Приближение к непрерывной памяти можно получить, если вы храните элементы (типа говорят T) в std::vector<T>, а затем использовать multi_index_container от std::ref<T> s. Конечно, это усложняет управление жизненным циклом объектов.

Edit: дизайн Обоснование

Есть целый ряд причин, почему примыкание памяти трудно/трудно включить в дизайне библиотеки:

  • стабильность Итератора обеспечиваются по всем показателям, а не просто произвольные. Было бы невозможно сохранить это (с разумной производительностью), если бы элементы хранились смежно в куске памяти.
  • Предположим, нам удалось каким-то образом получить индекс произвольного доступа, индуцирующий примыкание памяти к хранению элементов. Что произойдет, если у нас есть два индексов с произвольным доступом? Похоже, что первый индекс контейнера должен иметь особый статус с точки зрения диктовки макета всего контейнера, чтобы это удерживало воду.
  • Индексы неслучайного доступа основаны на узлах по необходимости.Это означает, что каждое значение хранится в большей структуре с комнатой для дополнительной информации (указатели rb-дерева и т. Д.). Если элементы были сохранены contiguoulsy, то либо a) это будут узлы, которые будут храниться смежно, а не сами значения , который кажется довольно бесполезным (подумайте, что вернется data()), или б) узлы должны быть отделены от значений, так что вместо того, чтобы встраивать значение в узел, у нас были бы узлы с указателями на смежно сохраненные значения , что является пустой тратой пространства и не выглядит как резонирующее решение по умолчанию.
+0

Это потому, что стабильность (стабильность) была приоритетной в дизайне? В принципе функция резервирования может достичь этого, но я предполагаю, что это сильно осложнило бы реализацию, нет? – alfC

+0

Я имею в виду в других словах, почему 'stable_vector' (или' multi_index') не резервирует непрерывную память (для узлов), если количество элементов известно заранее? (Я пытаюсь выяснить, есть ли какие-либо обстоятельства, при которых память может быть обманута, чтобы быть смежной, я не ищу гарантии при любых условиях.) – alfC

+1

Я добавил несколько комментариев к моему ответу, надеясь решить ваши вопросы. –