S
unskilled schrieb:
auch, wenns hier nicht um mich geht:
SP schrieb:
[...]std::iterator_traits für Deinen Iterator spezialisieren. Letzteres ist wahrscheinlich am besten, da Du schlecht pointer und reference sinnvoll definieren kannst.
wie meinst du das?
ob man iter-traits spez oder die typedefs ordentlich typedef-t ist doch dabei völlig egal - machen muss man es ja eh?
Man könnte std::iterator_traits spezialisieren und einige typedefs weglassen, wenn man das will. Ob das eine gute Idee ist, weiß ich nicht. Ich hatte mich damit bisher nicht richtig auseinander gesetzt.
Ein Blick in den Standard verrät, dass die Idee folgende ist:
typeid(reference) == typeid(*it)
typeid(pointer) == typeid(it->)
typeid(difference_type) == typeid(it-it)
wobei value_type und iterator_category auch "ordentlich" gesetzt sein sollten, (value_type sollte nie cv-qualifiziert sein).
Ein OutputIterator darf allerdings alles außer iterator_category auf void setzen.
Wie man diese typedefs bei einer "prozedural erzeugten Sequenz", bei der die Elemente nicht wirklich im Speicher stehen sondern on-the-fly erzeugt werden, sinnvoll definiert ist mir trotzdem nicht 100%ig klar. Vielleicht so ...
class nniter // natural number iterator
{
long v;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef long value_type;
typedef long const& reference;
typedef long const* pointer; // Typ von &*iter
typedef long difference_type;
nniter() : v(0) {}
reference operator*() const {return v;}
...
};
Der Haken ist allerdings, dass die von operator* zurückgegebene Referenz ungültig wird, wenn der Iterator zerstört wird. Alternativ dazu
class nniter // natural number iterator
{
long v;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef long value_type;
typedef long reference;
typedef void pointer; // Ausdruck &*iter ill-formed, daher void
typedef long difference_type;
nniter() : v(0) {}
long operator*() const {return v;}
...
};
Der Haken ist allerdings, dass reference wirklich eine Referenz sein sollte, falls es sich um einen ForwardIterator oder höher handeln sollte.
Gruß,
SP