Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Unterscheidung lesen/schreiben operator[]

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
04.01.2007, 14:18 Uhr
J-jayz-Z
Perl Crack ala Carte
(Operator)


Hi,

wenn ich den operator[] überlade, habe ich eine Funktion für den Lese und den Schreibzugriff. Wie kann ich unterscheiden, ob man nun gelesen oder geschrieben hat?
Ich habe in wie folgt überladen:

C++:
std::string& operator[](const std::string& foo)
{
    return Map[foo];
}

--
perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"'
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
04.01.2007, 14:33 Uhr
0xdeadbeef
Gott
(Operator)



C++:
std::string &operator[](std::string const &foo) // read-write
{
    return Map[foo];
}

std::string const &operator[](std::string const &foo) const// read-only
{
    return Map[foo];
}


...allerdings kannst du auf die Art nicht unterscheiden, ob nachher tatsächlich da rein geschrieben wird, sondern lediglich, ob eine konstante oder eine schreibbare Referenz angefordert wurde.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 04.01.2007 um 14:35 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.01.2007, 14:50 Uhr
J-jayz-Z
Perl Crack ala Carte
(Operator)


Das hatte ich schonmal probiert, kam die selbe Meldung wie jetzt

C++:
Configurator.hpp(31) : error C2678: Binärer Operator '[': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'const std::map<_Kty,_Ty>' akzeptiert (oder keine geeignete Konvertierung möglich)

--
perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"'
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.01.2007, 16:02 Uhr
0xdeadbeef
Gott
(Operator)


Ach ja, richtig - [] ist bei map nicht const. In dem Fall kannst dus per

C++:
std::string const &operator[](std::string const &foo) const// read-only
{
    return *Map.find(foo);
}


emulieren, glaube ich. wobei eine Fehlerbehandlung für nicht vorhandene Schlüssel hilfreich wäre.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 04.01.2007 um 16:03 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.01.2007, 16:26 Uhr
J-jayz-Z
Perl Crack ala Carte
(Operator)



C++:
return Map.find(foo)->second;

Funktioniert, es wird trotzdem jedesmal die read/write Konstruktion aufgerufen ...
So scheine ich wohl nicht weiter zu kommen
--
perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"'
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.01.2007, 23:36 Uhr
virtual
Sexiest Bit alive
(Operator)


Was aufgreufen wird hängt vom Kontext ab:

C++:
void f(some_class& x) {
    int i = x[0];   // Ruft read/write [] auf
}

void g(const some_class& x) { // beachte const
    int i = x[0];   // Ruft read only [] auf
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.01.2007, 09:28 Uhr
J-jayz-Z
Perl Crack ala Carte
(Operator)


Das ist mir klar. Ich will aber das bei

C++:
std::cout << x["test"] << std::endl;
das read-only Konstrukt aufgerufen wird. Ich weise damit ja nur std::ostream& operator<<(std::ostream&, myClass& ) . Wenn ich dasObjekt von myClass allerdings auf const setze, kann ich es ja nie schreiben. Also geht std::ostream& operator<<(std::ostream&, const myClass& ) auch nicht ...
Zwickmühle ... Ich schau mal, ob ich das irgendwie anderst implementiert bekomm ...
--
perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"'

Dieser Post wurde am 05.01.2007 um 09:29 Uhr von J-jayz-Z editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
05.01.2007, 10:27 Uhr
ao

(Operator)



Zitat von J-jayz-Z:
Wenn ich dasObjekt von myClass allerdings auf const setze, kann ich es ja nie schreiben. Also geht std::ostream& operator<<(std::ostream&, const myClass& ) auch nicht ...

Das versteh ich nicht, du schreibst doch auf den ostream, das myClass-Objekt wird nur gelesen. Müsste doch gehen, oder?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
05.01.2007, 10:51 Uhr
J-jayz-Z
Perl Crack ala Carte
(Operator)


Anscheinend funktioniert die Unterscheidung nur, wenn das Objekt const oder nicht const ist. Wenn ich das Objekt erstelle, will ich ja lesen und schreiben können. Also kann ich es nicht als const deklarieren. Also wird jedesmal die read/write Funktion aufgerufen, für nicht const Objekte. Egal ob ich lese oder schreibe ...
--
perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"'
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
05.01.2007, 11:43 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat von J-jayz-Z:
Anscheinend funktioniert die Unterscheidung nur, wenn das Objekt const oder nicht const ist.


Diesen Umstand wollte ich Dir in Post 005 klar machen.

Letztlich solltest Du auch folgendes beachten:
Intern scheinst Du in Deiner Klasse eine std::map zu nutzen. Wenn ich mich recht entsinne, dann hat eine Map gar keinen op[], welcher constant ist, weil nach einem

C++:
std::map<std::string,int> my_map;

int i = my_map["test"];


in my_map implizit ein Eintrag angelegt wird, auch wenn er vorher nicht da war. dh ein op[] ist auf einer Map überhaupt niemals konstant.

Es gibt zwei offenkundige Möglichkeiten, wie Du Dein Problem umgehen kannst:

1. Du verwendest nicht den op[] in den überladenenen Versionen für lesen/schreiben, sondern einfach get und set methoden (find ich pers. in der Regel schlauer)


2. Wenn Dir die Unterscheidung zwischen lese und schreib-Operationen wirklich wichtig ist und du irgendwie unbedingt den op[] verwenden willst dann wirst Du einen Proxyobject verwenden müssen, welches du anstelle des eigentlichen Objects bei dem op[] zurück gibst. Dieses Proxyobject muss einen
(a) Zuweisungoperator haben (write)
(b) Typ-Konvertierungs operator haben (read)

Also für ein int zB (kann man auch nen Template draus machen):

C++:
template<typename T>
class proxy {
    T value;
public:
     operator const T & () const { return value; }
     proxy& operator (const T& value) { this->value = value; return *this; }
    ...
};

class DeineKlasse {
      proxy<std::string> operator[] (const std::string& key) const { ... }
};


Du kannst nun lese und schreibzugriffe schön voneinander trennen und dennoch (mit einem gewissen Performancenachteil, den bei maps der op[] ohnehin nach sich zieht) mit dem op[] arbeiten.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 05.01.2007 um 11:46 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: