Ist das:Vorwärts Iterator/random acces Iterator und `Operator *` über temporäre Iteratoren
auto& ref1 = *it++;
ref1 = expression; // (1)
eine der erforderlichen Semantik eines Forward-Iterator? Und was ist mit einem Direktzugriffs-Iterator?
auto& ref1 = it[3];
ref1 = expression; // (2)
Nach cppreference
ein Vorwärts Iterator erforderlich ist, um:
// Return reference, which equals to (const) value_type &
*it++ === value_type&
und für einen Direktzugriffs Iterator:
it[n] === *(it + n)
die die gleiche Situation ist, das heißt, in beide, dass Situationen, in denen Sie ein Temporäres dereferenzieren (der Iterator). In meinem Fall speichert mein Iterator einen Index, der es ermöglicht, auf einen Container zuzugreifen, der keinen direkten Zugriff auf die gespeicherten Elemente bietet, nur über den Index.
Das funktioniert gut:
*it++ = value;
, da die temporäre Kopie von it
hat Satz Umfang.
Aber in diesem Fall:
type& val = *it++;
val = 3;
wir nicht definiertes Verhalten zu bekommen, da die Kopie bereits in der zweiten Zeile zerstört wird.
In meiner Situation habe ich einen QModelIndex
Wrapper, um Daten zu erhalten/speichern von/zu einem QAbstractItemModel
. Das Modell gibt Ihnen nur Kopien der auf dem Modell gespeicherten QVariant
s.
Meine Wrapper-Klasse (die value_type
mit dem operator=
überlastet) speichert eine Instanz eines QModelIndex
(das Modell zu manipulieren), und der Iterator eine Instanz dieser Wrapper. Also, wenn der Iterator zerstört ist, auch der Wrapper und der Index.
Ich denke, dass ich beide Probleme lösen kann, solange die Linien (1)
und nicht unterstützt werden müssen.
HINWEIS: Meine Implementierung ist wie, dass mehr oder weniger (vereinfacht):
// The value type
struct index
{
QModelIndex qidx;
index& operator=(QVariant const& val)
{
if (qidx.isValid())
qidx.model()->setData(qidx, val);
return *this;
}
};
// Private class actually. The "movements" cannot be done
// over the value type because it will cause, in functions
// returning references to the value type, to increase the chaos.
// So, I make the index points to different model items using
// this 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 it = it + n; // Operator+ is over there.
return { it.idx };
}
};
My Iterator dies unterstützen. Zwei Kopien desselben Iterators beziehen sich auf denselben Gegenstand. Welche mein Iterator fullfill nicht ist & * it == & * (my_row_it (it)). –