увеличить ошибки вставки мультииндекса с помощью boost :: tuple ссылок в качестве ключа для индекса order_unique

Я свел это к самому простому примеру кода, который я мог придумать.

У меня есть мульти-повышение, проиндексированное участником:

typedef const boost::tuple<const uint32_t &, const uint8_t &> key_type;

Делая это, кажется, заставьте мультииндекс думать, что каждый элемент равен (размер никогда не> 1)

Я сохраняю структуру с двумя членами, я хотел бы, чтобы оба этих индекса имели уникальный ключ для мультииндекса. Я думал, что создание набора ссылок сделает это довольно просто. Это не ведет себя, как я ожидал, хотя. Кажется, когда элементы в кортеже являются ссылками, каждый новый элемент конфликтует с существующим элементом. Вероятно, также стоит отметить, что простой уход от ссылок заставит код работать так, как я ожидаю, но это не помогает мне понять, почему эталонный случай не работает.

#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;
}

Как указано в примере, если я заставлю кортеж хранить значения, а не ссылки, все будет работать так, как я ожидал.

Я потратил время на изучение различных возможностей (висячие ссылки, сравнение наддува: наборы ссылок в небольших программах без многоиндексных и т. Д.)

Вот моя команда компиляции:
g ++ -O0 -ggdb -Wall -Werror test.cc -lboost_system -lpthread

Запуск программы дает:

itr = 1 10
itr = 1 10

Показывая, что, хотя я пытаюсь вставить 1,20 и 3,10, мульти кажется, что они равны 1,10.

Я довольно озадачен. Любая помощь приветствуется.

0

Решение

Копия семантики Item, как это реализовано в копии по умолчанию ctor, имеют недостатки. Предоставьте копию ctor следующим образом:

Item(const Item& x)
: thing1(x.thing1), thing2(x.thing2), key(thing2, thing1)
{}
2

Другие решения

Других решений пока нет …