我把它归结为我能想到的最简单的示例代码。
我有一个由成员编入索引的提升:
typedef const boost::tuple<const uint32_t &, const uint8_t &> key_type;
这样做似乎使多索引认为每个项目都相同(大小永远不会> 1)
我正在存储一个包含2个成员的结构,我希望多索引的唯一键是这两个成员。我认为制作一个参考元组可以很简单地完成这个。它的行为并不像我预期的那样。当元组中的项目引用时,似乎每个新项目都与现有项目冲突。可能还值得注意的是,简单地从引用中移开将使代码按照我的预期运行,但这并不能帮助我理解为什么引用案例不起作用。
#include <stdint.h>
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/tag.hpp>
#include "boost/tuple/tuple.hpp"
#include "boost/tuple/tuple_comparison.hpp"
namespace bmi = ::boost::multi_index;
class MyMultiIndex {
public:
MyMultiIndex() {}
~MyMultiIndex() {}
// Switching away from references fixes everything....
typedef const boost::tuple<const uint32_t &, const uint8_t &> key_type;
//typedef const boost::tuple<const uint32_t, const uint8_t> key_type;
struct Item {
const uint8_t thing1;
const uint32_t thing2;
key_type key;
Item(const uint8_t &a1, const uint32_t &a2)
: thing1(a1), thing2(a2), key(thing2, thing1)
{}
};
struct key_idx {};
typedef bmi::multi_index_container<
Item,
bmi::indexed_by<
bmi::ordered_unique<bmi::tag<key_idx>,
bmi::member<Item, key_type, &Item::key>
>
>
> imsi_map_type;
typedef imsi_map_type::index<key_idx>::type key_idx_type;
void insert(const uint8_t &a1, const uint32_t &a2)
{
Item item(a1, a2);
key_idx_type &idx(mi.get<key_idx>());
std::pair<key_idx_type::iterator, bool> ret = idx.insert(item);
if (!ret.second) {
std::cout << "itr = " << (int)ret.first->thing1 << " " << ret.first->thing2 << std::endl;
}
}
private:
imsi_map_type mi;
};
int
main()
{
MyMultiIndex mindex;
mindex.insert(1, 10);
mindex.insert(1, 20);
mindex.insert(3, 10);
return 0;
}
如示例中所述,如果我使元组保持值而不是引用每个工作,正如我所期望的那样。
我花了很多时间研究各种可能性(悬空引用,比较boost:较小程序中没有多索引的引用元组等)
这是我的编译命令: g ++ -O0 -ggdb -Wall -Werror test.cc -lboost_system -lpthread
运行程序给出:
itr = 1 10 itr = 1 10
显示即使我试图插入1,20和3,10,多人似乎认为他们等于1,10。
我很困惑。任何和所有的帮助表示赞赏。
答案 0 :(得分:2)
Item
的副本语义,由其默认副本ctor实现,存在缺陷。提供这样的副本:
Item(const Item& x)
: thing1(x.thing1), thing2(x.thing2), key(thing2, thing1)
{}