мультииндексный контейнер и элементы управления виртуальным списком

#c #user-interface #boost #boost-multi-index

#c #пользовательский интерфейс #повышение #boost-многоиндексный

Вопрос:

У меня возникли трудности с multi_index_container.

Это в основном то, что мне нужно:

  • Управление виртуальным списком.
  • Сортируйте элементы несколькими способами (поэтому я хотел использовать multi_index_container).
  • Доступ к элементам случайным образом, в соответствии с тем, как они отсортированы и отображаются в элементе управления списком.
  • Сохраняйте исходный порядок вставки / записи элементов.
  • Перемещайте элементы, вставляйте и удаляйте элементы в элементе управления списком (и соответствующим образом обновляйте контейнер).

До сих пор я синхронизировал несколько векторов / карт (отображал позиции списка, сопоставленные с реальными данными и т.д.), Поэтому было бы действительно неплохо перейти на multi_index_container.

Я пытался написать минимальную версию моего исходного кода (или пытается ее написать).

Большое спасибо за любую помощь в этом! 🙂

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

#include <cstring>

namespace bmi = boost::multi_index;
typedef unsigned int uint;

struct Item_t
{
public:
    Item_t(std::wstring name, uint quantity) : Name(name), Quantity(Quantity) {}

    std::wstring Name;
    uint Quantity;
    // more members here, such as item type, category, etc
};

struct record_order;
struct name_order;
struct quantity_order;

typedef bmi::multi_index_container<
    Item_t,
    bmi::indexed_by<
        bmi::random_access<>,
        bmi::sequenced<bmi::tag<record_order>>,
        bmi::ordered_non_unique<
            bmi::tag<name_order>,
            bmi::member<Item_t, std::wstring, amp;Item_t::Name>
        >,
        bmi::ordered_non_unique<
            bmi::tag<quantity_order>,
            bmi::member<Item_t, uint, amp;Item_t::Quantity>
        >
    >
> ItemContainer;

void populateContainer(ItemContaineramp; container)
{
    container.push_back(Item_t(L"Salmon roll", 3));
    container.push_back(Item_t(L"Chinese cola", 0));
    container.push_back(Item_t(L"Norwegian cap", 1));
    container.push_back(Item_t(L"Like-new socks", 3));
    container.push_back(Item_t(L"Empty bottle", 4));
    container.push_back(Item_t(L"Nice tie", 1));
    /* sorted:
        Chinese cola
        Empty bottle
        Like-new socks
        Nice tie
        Norwegian cap
        Salmon roll
    */
}

int wmain(int argc, wchar_t* argv[])
{
    ItemContainer container;
    populateContainer(container);

    // sort items to be displayed to the user, by Item_t::Name
    // Please see my comment regarding this
    container.rearrange(container.get<name_order>().begin());

    for (ItemContainer::iterator it = container.begin(), end_ = container.end(); it != end_;   it)
    {
        std::wcout << it->Name << std::endl;
    }

    std::wcout << std::endl;

    {
        // get Item_t from container where position in displayed list (after sort) is 5
        const Item_tamp; item = *(container.begin()   5);
        // "Salmon roll"
        std::wcout << item.Name << std::endl;
    }

    {
        // TODO: insert and sort automatically: Item_t(L"Another useless thing", 1)
        const Item_tamp; item = *(container.begin()   5);
        // Need this to be "Norwegian cap"
        std::wcout << item.Name << std::endl;
    }

    return 0;
}
  

Комментарии:

1. Я думаю, что теперь я кое-что понимаю rearrange() . Я обновил свой код.

2. Возможно, я был немного неправ. Я все равно обновил свой код.

3. Вам нужна база данных. вы можете что-то сшить с multi_index , но вам лучше использовать какую-то встроенную базу данных sql, например sqlite.org .

4. Спасибо, Дэни. Полномасштабный движок базы данных кажется мне немного перебором, но сортировка была бы легкой. Мне нужно было бы постоянно поддерживать синхронизацию базы данных с объектами Item_t. Данные, которые мне нужны для сортировки элементов, должны были бы находиться в базе данных, а также в объектах Item_t (поэтому у меня будут копии). Тем не менее, я обдумываю это. Тогда я имею в виду сохранение указателей на объекты Item_t, а также (копий) данных, по которым мне нужно отсортировать, в базе данных в памяти. Мне также все равно нужно было бы сохранить контейнер, который сопоставляет позиции списка с объектами Item_t (повышает производительность). А ты как думаешь?

5. Если это строго в памяти, вы можете просто сохранить указатель в базе данных (64-битное число) вместо копии Item_t. остальное легко настроить.