Proxy-Typ bei Iterator-Dereferenzierung
-
Ich bin eigentlich von vornherein davon ausgegangen, dass du genauw eißt, wo das Problem ist..
Nein, nein. Ich habe nur zu eng gedacht. Habe schließlich nicht die Erfahrung.

... und nur die Standardbiliothek übertölpeln wolltest.
Das versuche ich praktisch nie. Das ist nämlich sehr frickelig. Bei so etwas würde ich eigentlich sofort aussteigen und mein Design irgendwo weiter höher angucken.
Ein kleiner Scherz noch, analog zu deinem Code:
struct SonesUnmoeglicherIterator // oe { struct Proxy{...}; typedef Proxy value_type; typedef Proxy& reference; reference operator*() { static std::set<Proxy> set; return set.insert(Proxy(...)).first; } };Was natürlich eine doofe Anforderung stellt und dazu einen unnötigen Overhead hat. Vielleicht kann man den value_type noch hashen, dann ginge
unordered_set.
-
otze schrieb:
//edit siehe auch Tabelle 74 im C++03 Standard. C++11 ist mir Wumpe, wäre mir aber auch nicht bekannt, dass das geändert wurde.
Ignoranz ist kein besonders überzeugendes Argument.
1. Ja, C++11 führt hier notwenige Korrekturen durch: das Ergbnis der Dereferenzierung muss für InputIteratoren in value_type konvertierbar sein, und für ForwardIteratoren gleich reference.
2. swap sollte niemals qualifiziert aufgerufen werden, insbesondere stellt das SwapableRequirement auf den unqualifizierten Aufruf von swap ab. Jeder Aufruf von swap aus der Standardbibliothek heraus erfolgt somit unqualifiziert. Und nat. hat jeder vernünftig programmierter Proxy seine eigene swap-Funktion mitzubringen, da der normale Dreieckstausch offenbar nicht funktionieren kann.also
struct my_iterator { typedef whatever value_type; struct proxy { ... proxy& operator=(value_type); operator value_type(); ... friend void swap(proxy&,proxy&); }; typedef proxy reference; usw... reference operator*() const; };iterator::value_type tmp = *iter1; *iter1 = *iter2; *iter2 = tmp;funktioniert dann plötzlich auch wieder.
-
operator value_type();Absichtlich keine Referenz? Wie will dann jemand vom Proxy aus den Referee ändern?
Edit:
my_iteratormuss ein InputIterator oder OutputIterator sein.
-
Sone schrieb:
operator value_type();Absichtlich keine Referenz? Wie will dann jemand vom Proxy aus den Referee ändern?
Edit:
my_iteratormuss ein InputIterator oder OutputIterator sein.Indem die Zeile darüber genutzt wird?
-
camper schrieb:
Edit:
my_iteratormuss ein InputIterator oder OutputIterator sein.Indem die Zeile darüber genutzt wird?
Ja, aber was wenn Funktionen aufgerufen werden? Also keine nackten Zuweisungen?
Oder ist das vom Standard her nicht garantiert, dass das funktionieren muss?
-
Sone schrieb:
camper schrieb:
Edit:
my_iteratormuss ein InputIterator oder OutputIterator sein.Indem die Zeile darüber genutzt wird?
Ja, aber was wenn Funktionen aufgerufen werden? Also keine nackten Zuweisungen?
Kein Standardalgorithmus würde das tun (ausser über mem-Funktionszeiger).
-
camper schrieb:
Kein Standardalgorithmus würde das tun (ausser über mem-Funktionszeiger).
Es geht nicht darum, ob das ein Standardalgorithmus tun würde oder nicht tun würde, sondern ob er es darf. Darf er?
-
camper schrieb:
otze schrieb:
//edit siehe auch Tabelle 74 im C++03 Standard. C++11 ist mir Wumpe, wäre mir aber auch nicht bekannt, dass das geändert wurde.
Ignoranz ist kein besonders überzeugendes Argument.
Ignoranz der Realität auch nicht. Wieviele Softwarefirmen da draussen verwenden vc08? Ich sags dir: ziemlich viele. Wieviele Bibliotheken müssen c++03 noch unterstützen: ne ganze ecke mehr. Nur weil wir jetzt den magischen C++11 standard haben müssen wir nicht code propagieren, der in C++03 problemlos compiliert aber falsches Verhalten hat.
1. Ja, C++11 führt hier notwenige Korrekturen durch: das Ergbnis der Dereferenzierung muss für InputIteratoren in value_type konvertierbar sein, und für ForwardIteratoren gleich reference.
DAnn schauen wir uns doch mal an, als was reference in C++11 definiert ist.
Ich hab hier natürlich nicht den originalstandard rumligen sondern verwende den C++11 draft N3242. Wenn sich zwischen dem letzten draft und dem iso standard da noch was geändert hat: nur her damit. Da steht:24.2.5
Forward iterators
[forward.iterators]
A class or a built-in type X satisfies the requirements of a forward iterator if
— X satisfies the requirements of an input iterator (24.2.3),
— X satisfies the DefaultConstructible requirements (17.6.3.1),
— if X is a mutable iterator, reference is a reference to T; if X is a const iterator, reference is a reference to const TAlso ändert sich dort genau gar nichts.
2. swap sollte niemals qualifiziert aufgerufen werden
Die garantie dass das auch nicht passiert, haben wir aber erst seit C++11
-
Wenn sich zwischen dem letzten draft und dem iso standard da noch was geändert hat: nur her damit.
Du bist nicht besonders gut informiert, oder?
N3337Die Anforderungen für Forward-Iteratoren sind
A class or pointer type X satisfies the requirements of a forward iterator if
— X satisfies the requirements of an input iterator (24.2.3),
— X satisfies the DefaultConstructible requirements (17.6.3.1),
— if X is a mutable iterator, reference is a reference to T; if X is a const iterator, reference is a reference to const T,
— the expressions in Table 109 are valid and have the indicated semantics, and
— objects of type X offer the multi-pass guarantee, described below.
-
das ist exakt identisch? Da steht nun genau entweder reference ist T& oder T const&.
-
otze schrieb:
das ist exakt identisch? Da steht nun genau entweder reference ist T& oder T const&.
Mir war, als ob du das gar nicht geschrieben hattest... ??
Egal, jetzt hast du n3337-