C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

const iterator vom set

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Stephan Menzel
Guest





PostPosted: Mon Apr 10, 2006 5:04 pm    Post subject: const iterator vom set Reply with quote



G'day,

ich wollte kurz ein Thema ansprechen welches mir schon des oefteren
Kopfzerbrechen bereitet hat und mal Eure Meinung hoeren.

Folgende Situation:

class mystring : string {
public:
int getVal(void) const {return n;};
void setVal(int val) {n = val;};

private:
int n;
}

Das Member n ist fuer die Uniqueness im set irrelevant.
Nun verwende ich die Klasse in einem set und lasse mir von irgendwoher einen
Iterator reichen:

set<mystring>::iterator it = myset.begin();

Das hier nun:

it->setVal(42);

schlaegt zur Compilezeit fehl, weil der Iterator const sein muss, damit die
Sortierreihenfolge bzw. der Key unveraendert bleibt und die Seteigenschaft
erhalten bleibt. Soweit so klar, nur ist ja der Standardsetoperator < in
dieser Klasse nicht definiert und damit ist sicher, dass eine Veraenderung
von n keine Auswirkungen hat.

Warum darf ich das also immer noch nicht? Die Literatur sagt mir, dass
manche Compiler nur warnen wuerden, manche brechen ab. Meiner (g++-3.4)
bricht ab.

Waere es nicht moeglich, anhand der Tatsache, dass in mystring der operator<
nicht definiert ist, zu erkennen, dass alle private Members keine
Auswirkungen auf den Key haben koennen und folglich auch sicher gaendert
werden duerfen?

Oder gibt's da einen eleganten weg drumherum?
Bisher mach' ich das so:

const_cast<mystring&>(*it)->setVal(42);

Nur faende ich eine automatische Loesung schoener, denn das hier ist ja
schon irgendwie der Holzhammer mit dem man sich auch mal schoen selber in
die Pfanne hauen kann wenn man den operator< nun in mystring ploetzlich
auch definiert und irgend einen hypothetischen weiteren member dort mit
reinnimmt.

Viele Gruesse...

Stephan
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Rolf Magnus
Guest





PostPosted: Tue Apr 11, 2006 9:06 am    Post subject: Re: const iterator vom set Reply with quote



Stephan Menzel wrote:

Quote:
G'day,

ich wollte kurz ein Thema ansprechen welches mir schon des oefteren
Kopfzerbrechen bereitet hat und mal Eure Meinung hoeren.

Folgende Situation:

class mystring : string {
public:
int getVal(void) const {return n;};
void setVal(int val) {n = val;};

private:
int n;
}

Das Member n ist fuer die Uniqueness im set irrelevant.
Nun verwende ich die Klasse in einem set und lasse mir von irgendwoher
einen Iterator reichen:

set<mystring>::iterator it = myset.begin();

Das hier nun:

it->setVal(42);

Warum nimmst du nicht einfach std::map? Die ist doch genau für sowas
gedacht.

Quote:
schlaegt zur Compilezeit fehl, weil der Iterator const sein muss, damit
die Sortierreihenfolge bzw. der Key unveraendert bleibt und die
Seteigenschaft erhalten bleibt. Soweit so klar, nur ist ja der
Standardsetoperator < in dieser Klasse nicht definiert und damit ist
sicher, dass eine Veraenderung von n keine Auswirkungen hat.

Warum darf ich das also immer noch nicht?

Wenn das Objekt mal const ist, ist es ziemlich egal, wie dein operator<
definiert ist. Du darfst es nicht ändern.

Quote:
Die Literatur sagt mir, dass manche Compiler nur warnen wuerden, manche
brechen ab. Meiner (g++-3.4) bricht ab.

Waere es nicht moeglich, anhand der Tatsache, dass in mystring der
operator< nicht definiert ist, zu erkennen, dass alle private Members
keine Auswirkungen auf den Key haben koennen und folglich auch sicher
gaendert werden duerfen?

Möglich wäre das vermutlich schon, aber es würde halt der C++-Norm
widersprechen.

Quote:
Oder gibt's da einen eleganten weg drumherum?
Bisher mach' ich das so:

const_cast<mystring&>(*it)->setVal(42);

Nur faende ich eine automatische Loesung schoener, denn das hier ist ja
schon irgendwie der Holzhammer mit dem man sich auch mal schoen selber in
die Pfanne hauen kann wenn man den operator< nun in mystring ploetzlich
auch definiert und irgend einen hypothetischen weiteren member dort mit
reinnimmt.

Entweder wie schon erwähnt std::map nehmen oder dein Member n mutable
machen. Dann kannst du setValue() const machen und darin trotzdem n
verändern. Das ist zwar in diesem Fall auch eher unschön, aber immer noch
besser als der const_cast.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Stephan Lorsbach
Guest





PostPosted: Tue Apr 11, 2006 10:44 am    Post subject: Re: const iterator vom set Reply with quote



Back to top
Stefan Reuther
Guest





PostPosted: Tue Apr 11, 2006 6:06 pm    Post subject: Re: const iterator vom set Reply with quote

Hallo,

Stephan Menzel wrote:
Quote:
class mystring : string {
public:
int getVal(void) const {return n;};
void setVal(int val) {n = val;};

private:
int n;
}

Das Member n ist fuer die Uniqueness im set irrelevant.

Heißt im Klartext: es ist möglich, zwei 'mystring'-Objekte zu haben, die
von std::set als identisch betrachtet werden, es aber nicht sind (weil
sie verschiedene 'n' haben). Da hätte ich zumindest ein leicht flaues
Gefühl dabei.

Quote:
Waere es nicht moeglich, anhand der Tatsache, dass in mystring der operator
nicht definiert ist, zu erkennen, dass alle private Members keine
Auswirkungen auf den Key haben koennen und folglich auch sicher gaendert
werden duerfen?

Ja, das wäre nicht möglich.

// anderes_modul.cpp:
bool operator<(const yourstring& a, const yourstring& b)
{
return a.getVal() < b.getVal();
}

Quote:
Oder gibt's da einen eleganten weg drumherum?

mutable wäre eine Möglichkeit.


Stefan

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Stephan Menzel
Guest





PostPosted: Tue Apr 11, 2006 10:06 pm    Post subject: Re: const iterator vom set Reply with quote

Stefan Reuther wrote:

Quote:
Das Member n ist fuer die Uniqueness im set irrelevant.

Heißt im Klartext: es ist möglich, zwei 'mystring'-Objekte zu haben, die
von std::set als identisch betrachtet werden, es aber nicht sind (weil
sie verschiedene 'n' haben). Da hätte ich zumindest ein leicht flaues
Gefühl dabei.

Das war eine starke Vereinfachung die ich da skizzierte aber im Grunde
trifft es das, ja.
Etwas praxisnaeher waere zum Beispiel ein Setelement, welches von einer
Mutexklasse ableitet. Diese wuerde ein hypothetisches lock() oder unlock()
nicht const deklarieren koennen weil ja bei diesen Operationen ein Wert
veraendert wird. Dennoch waere dieser Mutex und sein Wert wohl kaum
geeignet um im Setoperator eine Rolle zu spielen.
Ein anderes Beispiel waere ein Timestamp. Hier koennte man sich das Set als
eine Art unique Queue vorstellen bei der Elemente durchaus mehrmals
eingefuegt werden koennen, man aber deswegen nicht jedesmal die ganze Queue
durchlaufen will nur um rauszufinden ob es schon drin ist. Also wuerde man
den Timestamp in operator< nicht mit aufnehmen. Man wuerde aber ggf.
spaeter die Gelegenheit wollen diesen zu aendern.
Ich hatte schon ab und an aus verschiedensten Gruenden dieses Problem und
konnte es eben bislang nur durch besagten cast loesen.

Quote:
Oder gibt's da einen eleganten weg drumherum?

mutable wäre eine Möglichkeit.

Also so etwa:

class mystring : string {
public:
int getVal(void) const {return n;};
void setVal(int val) {n = val;};

private:
mutable int n;
}

Klingt eigentlich wie genau das was ich brauche. Und haette nicht wie der
cast den Nachteil, dass ich ploetzlich auch fuer operator< relevantes
veraendern koennte. Super. Werd' ich mal probieren.

Danke und Gruesse...

Stephan
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
kanze
Guest





PostPosted: Wed Apr 12, 2006 2:06 pm    Post subject: Re: const iterator vom set Reply with quote

Stefan Reuther wrote:

Quote:
Stephan Menzel wrote:
class mystring : string {
public:
int getVal(void) const {return n;};
void setVal(int val) {n = val;};

private:
int n;
}

Das Member n ist fuer die Uniqueness im set irrelevant.

Heißt im Klartext: es ist möglich, zwei 'mystring'-Objekte zu
haben, die von std::set als identisch betrachtet werden, es
aber nicht sind (weil sie verschiedene 'n' haben). Da hätte
ich zumindest ein leicht flaues Gefühl dabei.

Kommt darauf an. So arbeiten die meisten Datenbanken: der
Schlüssel besteht aus bestimmten Felder im Satz (oder Spalte in
der Zeile, in Datenbank'sch).

In solchen Fällen halte ich meistens eine Set von Zeiger auf den
Objekte. Der Zeiger kann man nicht ändern; dazu gibt es auch
keine Funktionnen in der Klasse, um die Schlüsselfelder zu
ändern.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Stephan Menzel
Guest





PostPosted: Sat Apr 15, 2006 12:49 am    Post subject: Re: const iterator vom set Reply with quote

kanze wrote:

Quote:
Kommt darauf an. So arbeiten die meisten Datenbanken: der
Schlüssel besteht aus bestimmten Felder im Satz (oder Spalte in
der Zeile, in Datenbank'sch).

Genau so ist es.

Quote:
In solchen Fällen halte ich meistens eine Set von Zeiger auf den
Objekte. Der Zeiger kann man nicht ändern; dazu gibt es auch
keine Funktionnen in der Klasse, um die Schlüsselfelder zu
ändern.

Wobei das ja hier kein Problem waere, wenn ein Zeiger const ist, dann
letztlich ist er das ja meistens. In dem Fall wuerde ja das Object
interessieren worauf er zeigt.

Ausserdem koennte man beim blossen Speichern von Zeigern ja problemlos
identische Objekte wieder und wieder einfuegen, was ja gerade das ist was
ich hier nicht wollte.
Die Loesung mit dem Mutable gefaellt mir hier sehr gut.

Gruesse...

Stephan
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
kanze
Guest





PostPosted: Tue Apr 18, 2006 11:06 am    Post subject: Re: const iterator vom set Reply with quote

Stephan Menzel wrote:
Quote:
kanze wrote:

Kommt darauf an. So arbeiten die meisten Datenbanken: der
Schlüssel besteht aus bestimmten Felder im Satz (oder Spalte
in der Zeile, in Datenbank'sch).

Genau so ist es.

In solchen Fällen halte ich meistens eine Set von Zeiger auf
den Objekte. Der Zeiger kann man nicht ändern; dazu gibt es
auch keine Funktionnen in der Klasse, um die Schlüsselfelder
zu ändern.

Wobei das ja hier kein Problem waere, wenn ein Zeiger const
ist, dann letztlich ist er das ja meistens. In dem Fall wuerde
ja das Object interessieren worauf er zeigt.

Ausserdem koennte man beim blossen Speichern von Zeigern ja
problemlos identische Objekte wieder und wieder einfuegen, was
ja gerade das ist was ich hier nicht wollte.

Kommt darauf an. In std::set kann man höchst ein Element mit
derselben Schüssel einfügen.

Ein anderer Vorteil von Zeigern ist, dass man die Elemente in
mehreren set enthalten kann, mit unterschiedenen
Schlüsselfeldern. Wenn ich so was ähnlich gemacht habe, hatte
ich 6 sets insgesamt, hinter einer Fassade. Wenn ich ein Element
ändern wollte, gabe es eine Sonderfunktion der Fassade, die das
Element temporär aus den sets entfernt, und mir einen
Smartpointer auf dem Element zurückliefert. Der Destruktor des
Smartpointers fügt das Element wieder in die sets ein -- in
meinem Fall, die Änderungen könnten die Schlüssel ändern.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.