While working boost intrusive container splay_set, i have to reset local iterator member variables. Please see sample code below -
#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;
};
Intrusive container doesn't support assignment i suppose. I also cannot initialize splay_set
iterator via member initializer list. There is so limited example on boost and other site. None gives clear answer to this question.
My question is what should i do to assign a new value to a splay_set iterator (and in general sense to a intrusive container.)
The reason why you get
const_iterator
s mostly is because modifying fields may break container invariants.E.g. when building a set across elements of
struct { int key; std::string value; };
, modifying thekey
field through the iterator would lead to [Undefined Behaviour]The clean way to update things would be to first remove, then reinsert the modified item.
If this really hurts performance too badly
mutable
members for non-key fields, consider including the non-key data by reference)const_cast<>
to cast away the const. DANGER Don't pass this reference to any other party, because they will break the container invariants since they might not know to leave the key fields alone