0

私はこれを私が考えることができる最も単純なサンプルコードに要約しました。

メンバーによってインデックス付けされたブーストマルチがあります:

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

例で述べたように、タプルに値を保持させ、すべてを参照しない場合は、期待どおりに機能します。

私はさまざまな可能性を調査することに時間を費やしました(参照をぶら下げる、ブーストを比較する:マルチインデックスのない小さなプログラムでの参照のタプルなど)

これが私のコンパイルコマンドです:g ++ -O0 -ggdb -Wall -Werror test.cc -lboost_system -lpthread

プログラムを実行すると、次のようになります。

itr = 1 10 itr = 1 10

私が1,20と3,10を挿入しようとしているにもかかわらず、マルチはそれらが1,10に等しいと考えているように見えることを示しています。

私はかなり困惑しています。ありとあらゆる助けをいただければ幸いです。

4

1 に答える 1

2

Itemデフォルトのcopyctorによって実装されているように、のコピーセマンティクスには欠陥があります。次のようなコピーコンストラクタを提供します。

Item(const Item& x)
  : thing1(x.thing1), thing2(x.thing2), key(thing2, thing1)
{}
于 2012-09-07T17:41:56.947 に答える