c++ - Forward iterator/random acces iterator and `operator*` over temporary iterators -


is this:

auto& ref1 = *it++; ref1 = expression; // (1) 

one of required semantics of forward iterator? , random access iterator?

auto& ref1 = it[3]; ref1 = expression; // (2) 

according cppreference, forward iterator required to:

// return reference, equals (const) value_type & *it++ === value_type& 

and random access iterator:

it[n] === *(it + n) 

which same situation, means in both situations dereferencing temporary (the iterator). in case, iterator stores copy index allows access container doesn't provide direct access stored elements, through index.

that works fine:

*it++ = value; 

since temporary copy of it has sentence scope.

but in case:

type& val = *it++; val = 3; 

we undefined behaviour, since copy destroyed in second line.

in situation, have qmodelindex wrapper data/save from/to qabstractitemmodel. model gives copies of qvariants stored on model.

my wrapper class (the value_type operator= overloaded) saves instance of qmodelindex (to manipulate model), , iterator instance of wrapper. so, if iterator destroyed, wrapper , index too.

i think can solve both problems far lines (1) , (2) don't need supported.

note: implementation more or less (simplified):

// value type struct index {     qmodelindex qidx;      index& operator=(qvariant const& val)     {         if (qidx.isvalid())             qidx.model()->setdata(qidx, val);          return *this;     } };  // private class actually. "movements" cannot done // on value type because cause, in functions // returning references value type, increase chaos. // so, make index points different model items using // class. struct index_manipulator {     qmodelindex& qidx;      void move(int rows, int cols)     {         if (qidx.isvalid())             qidx = qidx.model()->index(qidx.row() + rows,                                        qidx.column() + cols);     } };  struct index_safe_ref {     mutable index idx;     operator index&() const { return idx; } };  struct my_row_it {     index idx;     index_manipulator manip = {idx.qidx};      my_row_it(qabstractitemmodel* m, int col)         : idx(m ? m->index(0, col) : qmodelindex())     {}      index& operator*() const { return idx; }      my_row_it operator++(int) const     {         auto copy = it;         manip.move(1, 0);         return copy;     }      index_safe_ref my_row_it::operator[](difference_type n) const     {        auto = + n; // operator+ on there.        return { it.idx };     } }; 

a stashing iterator (that is, iterator returns reference within itself) never valid forward iterator.

iterators in general must copyconstructible ([iterator.iterators]/2.1, requires, among other things, copy of iterator equivalent original. follows forward iterator , copy must compare equal, , [forward.iterators]/6 requires that 2 equal dereferenceable iterators a , b, *a , *b must bound same object, cannot satisfied stashing iterators.

if need ignore requirement, suggest ignoring 1 says reference must actual reference type, turning stashing iterator proxy iterator. there's established practice in standard library (vector<bool>::iterator) , breakage loud compile-time error, rather silent runtime mischief.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -