3

申し訳ありませんが、タイトルを具体的にすることはできません。

クラス Foo があるとしましょう

class Foo {
public:
    Foo() { m_bitset.reset(); }

    void set_i(int i) {
        m_bitset.set(1);
        m_i = i;
    }

    void set_j(int j) {
        m_bitset.set(2);
        m_j = j;
    }
    bool i_set() { return m_bitset(1); }
    bool j_set() { return m_bitset(2); }
    void clear_i() { m_bitset.reset(1); }
    void clear_j() { m_bitset.reset(2); }
    int get_i() {
        assert(i_set());
        return m_i;
    }
    int get_j() {
        assert(j_set());
        return m_j;
    }

private:
    int m_i, m_j;
    bitset<2> m_bitset;
};

そして今、Foo を multi_index に入れたいと思います。

typedef multi_index_container <
    Foo, 
    indexed_by<
        ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_i)
        >,
        ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_j)
        >
    >
> Foo_set;

私が理解しようとしているのは、私の multi_index が i または j の有効な値を持つ Foo をソートし (composite_key の場合は両方とも)、残りを渡す方法です。したがって、以下のコードは必要ありません。爆破するには、i に有効な値を持つ foo のみを返したいだけです。

for (Foo_set::nth_index<1>::type::iterator it = foos.get<1>().begin(); it != foos.get<1>().end(); ++it)
    cout << *it;
4

2 に答える 2

1

ブーストmulti_indexライブラリのドキュメントをざっと見てみると、このライブラリでは必要なことは不可能だと思います。その理論的根拠を見ると、すべての「次元」にわたって完全に索引付け可能な要素の索引付けのためにのみ作成されているように見えます。(ブーストユーザーのメーリングリストで、「スパース」インデックスディメンションを許可するハックがあるかどうかを尋ねてみてください。)

とにかく-問題の正確な性質によっては、インデックスタイプとしてboost::optionalを使用することで問題を回避できる場合があります。(boost ::optionalでインデックスを作成できるかどうかさえわかりませんが。)

于 2010-09-06T11:14:16.153 に答える
1

and関数を使用assert()すると、 multi_indexがインデックス作成のためにorの値を要求したときに、プログラムがハード ストップします。get_i()get_j()ij

Null Object Pattern の動作が必要なようです。つまりm_i、 andm_jは、設定されていないことを示すために特別な値を取るデータ型です (それらがポインターである場合、NULLポインターはこの目的に役立ちます)。次に、マルチインデックスはそれらの値にインデックスを付けて、すべてのnull値をまとめます。

データにアクセスするときは、boost::rangeを使用して null 値を除外できます。

// Predicate for null testing
struct is_not_null {
    bool operator()(const Foo& f) { return f.get_i() != NULL && f.get_j() != NULL; }
};

Foo_set::nth_index<1>::type& idx = foos.get<1>();
BOOST_FOREACH(const Foo& f, idx | filtered(is_not_null())) {
    ;// do something with the non-null Foo's
}

変数の値空間を汚染したくない場合 (つまり、格納できる意味のある null 値がない場合)、m_iおよびm_jメンバーをboost::optionalに変換することも検討できます。もう少しファンクターをラッピングすると、 の複合インデックスを作成できます。これにより、 set または unset に個別<bool, int>にアクセスできます。のような複合インデックスを使用して、結合Fooするインデックスをさらに構成できます。ij<bool, bool, int, int>

于 2011-02-09T22:33:15.197 に答える