0

I have boiled this down to the simplest example code I could think of.

I have a boost multi indexed by a member:

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

Doing this seems make the multi-index think every item is equal (size is never > 1)

I am storing a structure with 2 members, I would like a unique key for the multi-index to be both of those members. I thought making a tuple of references would accomplish this fairly simply. It does not behave as I expected though. It seems when the items in the tuple are references every new item conflicts with the existing item. It is probably also worth noting that simply moving away from references will make the code behave as I expect, but that doesn't help me understand why the reference case isn't working.

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

As stated in the example if I make the tuple hold values and not references everyting works as I am expecting.

I have spent time looking into various possibilities (dangling references, comparing boost:tuples of references in a smaller program with no multi-index, etc)

Here is my compilation command: g++ -O0 -ggdb -Wall -Werror test.cc -lboost_system -lpthread

running the program gives:

itr = 1 10 itr = 1 10

Showing that even though I am trying to insert 1,20 and 3,10 the multi seems to think they are equal to 1,10.

I am quite perplexed. Any and all help is appreciated.

user442585
  • 571
  • 1
  • 9
  • 17
  • Nobody cares if the ["title says it all"](http://meta.stackexchange.com/q/145019/163768). People who've opened this page don't necessarily want to have to piece together what you mean. Just write a self-contained, clear body. – Kerrek SB Sep 07 '12 at 15:19
  • Thans you, that is a good point. I have changed the current question (hopefully for the better) and will keep this in mind when posting future questions. – user442585 Sep 07 '12 at 17:48

1 Answers1

2

The copy semantics of Item, as implemented by its default copy ctor, are flawed. Provide a copy ctor like this:

Item(const Item& x)
  : thing1(x.thing1), thing2(x.thing2), key(thing2, thing1)
{}
Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20
  • And going to the initial problem you wanted to solve, Boost.MultiIndex provides composite keys without the need to resort to the kind of tuple constructs you're experimenting with: http://www.boost.org/libs/multi_index/doc/tutorial/key_extraction.html#composite_keys – Joaquín M López Muñoz Sep 07 '12 at 17:58
  • How fortunate for me that the multi-index author contributes on S.O. :) – user442585 Sep 07 '12 at 18:11