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, &Item_t::Name>
>,
bmi::ordered_non_unique<
bmi::tag<quantity_order>,
bmi::member<Item_t, uint, &Item_t::Quantity>
>
>
> ItemContainer;
void populateContainer(ItemContainer& 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_t& 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_t& item = *(container.begin() + 5);
// Need this to be "Norwegian cap"
std::wcout << item.Name << std::endl;
}
return 0;
}