0

押し付けがましいコンテナー splay_set の作業中に、ローカル イテレーター メンバー変数をリセットする必要があります。以下のサンプルコードを参照してください -

#include <boost/intrusive/splay_set.hpp>

using namespace boost::intrusive;

class Obj
{
    public:
        Obj(){};
        ~Obj(){};

        boost::intrusive::list_member_hook<boost::intrusive::link_mode<boost::intrusive::normal_link> > m_memberHook;
    private:
        int a;
};

typedef splay_set<Obj, compare<greater<Obj> >, member_hook<Obj, 
                splay_set_member_hook<boost::intrusive::link_mode<boost::intrusive::normal_link> >,
                &Obj::m_memberHook> > StorageSSet;
typedef StorageSSet::iterator   StorageSSetIter;

class Storage
{
    public:

        bool init(StorageSSet& sset)
        {
            // Error: "no match for operator= in ..."
            m_curIter = sset.begin();  ////<<<<------------- How to set new iterator
            m_endIter = sset.end();    ////<<<<------------- How to set new iterator
        }

    protected:

        StorageSSetIter     m_curIter;
        StorageSSetIter     m_endIter;
};

侵入型コンテナは割り当てをサポートしていないと思います。splay_setまた、メンバー初期化子リストを介してイテレータを初期化することもできません。ブーストや他のサイトには非常に限られた例があります。この質問に対する明確な答えはありません。

私の質問は、新しい値を splay_set イテレータに割り当てるにはどうすればよいかということです (一般的には、侵入型のコンテナに)。

4

1 に答える 1

3

ほとんどの場合 sを取得する理由const_iteratorは、フィールドを変更するとコンテナーの不変条件が壊れる可能性があるためです。

たとえば、 の要素にまたがるセットを構築する場合、イテレータを使用してフィールドをstruct { int key; std::string value; };変更すると、[未定義の動作] が発生します。key

物事を更新するきれいな方法は、最初に削除してから、変更された項目を再挿入することです。

これが本当にパフォーマンスに深刻な影響を与える場合

  1. 設計を再検討してください (mutable非キー フィールドのメンバーを検討し、参照によって非キー データを含めることを検討してください) 。
  2. const_cast<>を使用して const をキャストすることにより、抽象化に穴を開けます。危険このリファレンスを第三者に渡さないでください。キー フィールドをそのままにしておくことを知らない可能性があるため、コンテナの不変条件が壊れてしまうからです。
于 2014-11-27T08:56:40.527 に答える