0

クラスにプライベート スコープの Boost.BiMap があり、このマップの一部のパブリック ビューをエクスポートしたいと考えています。次のコードについて 2 つの質問があります。

class Object {

    typedef bimap<
        unordered_set_of<Point>,
        unordered_multiset_of<Value>
    > PointMap;

    PointMap point_map;

public:
    ??? GetPoints(Value v) {
    ...
}

Point最初の質問は、 に関連付けられた を取得する反復の方法Valueが正しいかどうかです。以下は、ポイントを反復処理するために使用しているコードです。私の質問は、it->first == value条件を含める必要があることがわかったため、正しく反復しているかどうかであり、私が知らない可能性のあるより良いインターフェイスを考えると、これが必要かどうかはわかりませんでした。

PointMap::right_const_iterator it;
it = point_map.right.find(value);
while (it != point_map.right.end() && it->first == val) {
    /* do stuff */
}

???2 番目の質問は、bimap イテレータを公開せずに GetPoints (上記の戻り値の型) のパブリック ビューを提供する最善の方法は何かということpoint_map.right.end()です。参照のリストやセットなどの効率的な構造であれば機能しますが、コレクションを作成する方法が少しわかりません。

ありがとう!

4

1 に答える 1

0

最初の質問:

unordered_multiset_ofbimap タイプの右側にコレクション タイプを使用しているため、 と互換性のあるインターフェイスを持つことになりますstd::unordered_multimapstd::unordered_multimap1 つは目的のキーを持つ最初の要素を指し、もう 1 つは同じキーを持つ要素の範囲の末尾を 1 つ過ぎた要素を指しますequal_range(const Key& key)std::pairこれを使用すると、キーと反復条件の値を比較せずに、一致するキーを使用して範囲を反復処理できます。

http://www.boost.org/doc/libs/1_41_0/libs/bimap/doc/html/boost_bimap/the_tutorial/controlling_collection_types.htmlおよびhttp://en.cppreference.com/w/cpp/container/unordered_multimapを参照してください参照用の/equal_range

2 番目の質問:

一致する値を持つ要素へのポインターまたは参照のリストまたはその他の実際のコンテナーを構築し、それを返すことは、常に O(n) スペースを必要とするため非効率的ですが、ユーザーが元の bimap の範囲を反復処理するだけで十分です。 O(1) メモリのみを必要とする 2 つのイテレータを返します。

イテレータを直接返すメンバー関数を書くことができます。

typedef PointMap::right_const_iterator match_iterator;

std::pair<match_iterator, match_iterator> GetPoints(Value v) {
    return point_map.right.equal_range(v);
}

または、begin() および end() メンバー関数がこれら 2 つの反復子を返すようにすることで、コンテナーのようなインターフェイスを提示するプロキシ クラスを作成し、GetPoints()メンバー関数がその型のオブジェクトを返すようにすることもできます。

class MatchList {

    typedef PointMap::right_const_iterator iterator;

    std::pair<iterator, iterator> m_iters;

public:

    MatchList(std::pair<iterator, iterator> const& p) : m_iters(p) {}

    MatchList(MatchList const&) = delete;

    MatchList(MatchList&&) = delete;

    MatchList& operator=(MatchList const&) = delete;

    iterator begin() { return m_iters.first; }

    iterator end() { return m_iters.second; }
};

コピー不可、移動不可、および割り当て不可にすることをお勧めします (関連するメンバー関数を削除することで上記で行ったように)。そうしないと、ユーザーがプロキシ クラスのコピーを保持し、後で反復子が無効になる可能性があるときにそれにアクセスしようとする可能性があるためです。 .

最初の方法はコードの記述を減らすことを意味し、2 番目の方法はより一般的なインターフェイスをユーザーに提示することを意味します (また、後で実装を変更する必要がある場合は、プロキシ クラスにより多くのものを隠すことができます)。

于 2012-01-28T20:23:26.867 に答える