увеличить ошибки вставки нескольких индексов с помощью 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;
}

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

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

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

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

ит = 1 10 ит = 1 10

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

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


person user442585    schedule 07.09.2012    source источник
comment
Никому нет дела до того, что заголовок говорит сам за себя. Люди, открывшие эту страницу, не обязательно хотят разбираться в том, что вы имеете в виду. Просто напишите автономный, ясный корпус.   -  person Kerrek SB    schedule 07.09.2012
comment
Спасибо, это хороший момент. Я изменил текущий вопрос (надеюсь, к лучшему) и буду помнить об этом при публикации будущих вопросов.   -  person user442585    schedule 07.09.2012


Ответы (1)


Семантика копирования Item, реализованная по умолчанию, имеет недостатки. Предоставьте копировальный центр следующим образом:

Item(const Item& x)
  : thing1(x.thing1), thing2(x.thing2), key(thing2, thing1)
{}
person Joaquín M López Muñoz    schedule 07.09.2012
comment
И переходя к исходной проблеме, которую вы хотели решить, Boost.MultiIndex предоставляет составные ключи без необходимости прибегать к конструкциям кортежей, с которыми вы экспериментируете: boost.org/libs/multi_index/doc/tutorial/ - person Joaquín M López Muñoz; 07.09.2012
comment
Как мне повезло, что автор мультииндекса вносит свой вклад в S.O. :) - person user442585; 07.09.2012