(不通过容器迭代)
我尝试用一个boost :: multi_index_container替换多个std容器。
下面的boost :: multi_index_container有两个索引
using Boxes = boost::multi_index_container<
Box,
indexed_by<
sequenced<
tag<ordered_by_insertion>
>,
ordered_unique<
tag<ordered_by_id>,
const_mem_fun<Box, set_id_type_const_reference, &Box::id>
>
>
>;
需要保留元素添加到容器的顺序, 所以第一个索引是插入序列(ordered_by_insertion)。
元素由id唯一标识, 所以第二个索引是唯一的id(ordered_by_id)。
如何使用唯一ID来有效地检索元素的插入顺序位置。
有没有办法将 ordered_by_insertion 转换为从对象到位置的双向地图? 或者从Box :: id到位置创建第三个索引?
答案 0 :(得分:4)
以下projects从索引#1到索引#0的迭代器:
Boxes b=...;
auto it1=b.get<1>().find(id);
auto it0=b.project<0>(it1);
您可以从中获取索引#0中的位置,但是线性时间,因为序列索引迭代器只是双向的:
auto pos=std::distance(b.begin(),it0);
好消息是,如果您使用random_access
索引而不是sequenced
,则计算pos
是常数时间;你甚至可以简单地写它:
auto pos=it0-b.begin();
答案 1 :(得分:3)
你可以这样做:
<强> Live On Coliru 强>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <iostream>
namespace bmi = boost::multi_index;
using set_id_type_const_reference = int const&;
struct Box {
int _id;
std::string name;
set_id_type_const_reference id() const { return _id; }
};
using Boxes = boost::multi_index_container<
Box,
bmi::indexed_by<
bmi::sequenced<bmi::tag<struct ordered_by_insertion> >,
bmi::ordered_unique<
bmi::tag<struct ordered_by_id>,
bmi::const_mem_fun<Box, set_id_type_const_reference, &Box::id>
>
>
>;
int main() {
Boxes boxes { {1,"One"}, {17,"Seventeen"}, {8,"Eight"}, {3,"Three"} };
auto& by_ins = boxes.get<ordered_by_insertion>();
auto& by_id = boxes.get<ordered_by_id>();
for (auto i : { 8,17,1,3 }) {
auto it = by_id.find(i);
auto position = distance(by_ins.begin(), bmi::project<0>(boxes, it));
std::cout << "Found " << it->name << " with insertion-order position " << position << "\n";
}
}
打印:
Found Eight with insertion-order position 2
Found Seventeen with insertion-order position 1
Found One with insertion-order position 0
Found Three with insertion-order position 3
考虑使用random_access
来提高distance
通话效率:http://www.boost.org/doc/libs/1_60_0/libs/multi_index/doc/reference/rnd_indices.html