#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. остальное легко настроить.