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 

Warum nicht this->[2] ?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
helmut.weil@t-online.de
Guest





PostPosted: Tue May 23, 2006 9:33 am    Post subject: Warum nicht this->[2] ? Reply with quote



Hallo

Wenn ich in einer Klasse den operator[] (int) definiere, ist es nicht
möglich, in einer Member-Funktion diesen mit der normalen Syntax zu
benutzen

class A{
...........
public:
double oberator[] (int a){
............
return ....}

void f(){
double temp =this->[a]; //FEHLER !!!
double temp =[a]; //FEHLER, ist aber auch haesslich !!!
double temp =this->operator[a]; //OK
}};
Hat das einen besonderen Grund ausser dass die Schreibweise etwas
ungewöhnlich wirkt ?
(gnu-Compiler)

Gruss

Helmut

--
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
Daniel Albuschat
Guest





PostPosted: Tue May 23, 2006 12:21 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote



helmut.weil@t-online.de wrote:
Quote:
Hallo

Wenn ich in einer Klasse den operator[] (int) definiere, ist es nicht
möglich, in einer Member-Funktion diesen mit der normalen Syntax zu
benutzen

class A{
..........
public:
double oberator[] (int a){
...........
return ....}

void f(){
double temp =this->[a]; //FEHLER !!!
double temp =[a]; //FEHLER, ist aber auch haesslich !!!
double temp =this->operator[a]; //OK

Nicht OK!
Richtig Syntax waere this->operator[](a);

Quote:
}};
Hat das einen besonderen Grund ausser dass die Schreibweise etwas
ungewöhnlich wirkt ?
(gnu-Compiler)

Das hat den Grund, dass -> ein binaerer operator ist, auf dessen rechte
Seite ein Member stehen muss (und kein Operator sein darf).
(*this)[a] waere auch moeglich, da * ein unaerer Operator ist.
Aber this-> oder (*this) benutzt man eigentlich eh nur, wenn man etwas
falsch gemacht hat. Der richtige Weg waere IMHO:

double temp = operator[](a);

MfG,
Daniel

--
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
helmut.weil@t-online.de
Guest





PostPosted: Tue May 23, 2006 4:41 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote



Einleuchtend :-)

danke Daniel

Helmut

--
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
Heinz Ozwirk
Guest





PostPosted: Tue May 23, 2006 8:30 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote

<helmut.weil@t-online.de> schrieb im Newsbeitrag
news:1148362418.176173.215550 (AT) j33g2000cwa (DOT) googlegroups.com...
Quote:
Hallo

Wenn ich in einer Klasse den operator[] (int) definiere, ist es nicht
möglich, in einer Member-Funktion diesen mit der normalen Syntax zu
benutzen

class A{
..........
public:
double oberator[] (int a){
...........
return ....}

void f(){
double temp =this->[a]; //FEHLER !!!
double temp =[a]; //FEHLER, ist aber auch haesslich !!!
double temp =this->operator[a]; //OK

Nicht OK. Es muss this->operator[](a) heißen.

Quote:
}};
Hat das einen besonderen Grund ausser dass die Schreibweise etwas
ungewöhnlich wirkt ?

Die Funktion heißt nun einmal operator[]. Also muss man den Namen auch so
schreiben. Die Kurzform a[i] ist im Prinzip eine Abkürzung für
a.operator[](i). Anstatt

this->operator[](a);

könntest du also auch

(*this)[a];

schreiben.

Heinz

--
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 May 24, 2006 9:21 am    Post subject: Re: Warum nicht this->[2] ? Reply with quote

helmut.weil@t-online.de wrote:

Quote:
Wenn ich in einer Klasse den operator[] (int) definiere, ist
es nicht möglich, in einer Member-Funktion diesen mit der
normalen Syntax zu benutzen

class A{
..........
public:
double oberator[] (int a){
...........
return ....}

void f(){
double temp =this->[a]; //FEHLER !!!
double temp =[a]; //FEHLER, ist aber auch haesslich !!!
double temp =this->operator[a]; //OK

Echt! Soll nicht gehen, soweit ich weiß. Hast du nicht ehe:
double temp = this->operator[]( a ) ;
geschrieben?

Geht auch:
double temp = operator[]( a ) ;
double temp = (*this)[ a ] ;

Quote:
}};

Hat das einen besonderen Grund ausser dass die Schreibweise
etwas ungewöhnlich wirkt ?

Kommt mehr oder weniger aus der Grammatik her. a[b] is erlaubt;
einfaches [b] nicht, auch wenn wie hier man einen impliziten a
finden könnte. Also, (*this)[a], aber nicht einfach [a].

Die Schreibweise außer (*this)[a], die gehen, gehen weil
operator[] (auch wenn es drei Tokens sind) gilt als Name der
Funktion. Also: alle Syntaxe, die mit f() gehen, gehen auch mit
operator[]().

--
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
Daniel Albuschat
Guest





PostPosted: Tue May 30, 2006 7:50 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote

Rolf Magnus wrote:

Quote:
Ein Stück Code sagt mehr als tausend Worte:

#include <iostream

class Base
{
public:
void foo() { std::cout << "foo\n"; }
};

template<typename X
class Derived : public X
{
public:
Derived() { this->foo(); }

};

int main()
{
Derived<Base> d;
}

Wenn du oben im Konstruktor von Derived das "this->" wegnimmst, ist der Code
nicht korrekt, weil der Compiler an der Stelle noch nicht weiß, daß foo()
eine Memberfunktion sein soll.
Zumindest neuere Compiler werden den Code nur mit "this->" akzeptieren.

Achso. Ich hatte spontan nur das typename-Problem im Kopf, aber bei
Methoden und anderen Membern ist das natuerlich etwas Anderes.
Aber ob das ein Defekt im Standard ist, weiss ich nicht.
Schliesslich kann der Compiler dadurch, falls foo() nirgends (ausser in
der Basisklasse) definiert ist, hier bereits fruehzeitig meckern, dass
foo() nicht existiert. Aber das kann ein Vor- und ein Nachteil sein. Wink
Aber ich habe schon zu lange kein kein templatereiches C++ mehr
geschrieben, um mich da spontan gut reindenken zu koennen.

MfG,
Daniel

--
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
Christoph Bartoschek
Guest





PostPosted: Tue May 30, 2006 9:58 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote

Rolf Magnus wrote:

Quote:
Ein Stück Code sagt mehr als tausend Worte:

#include <iostream

class Base
{
public:
void foo() { std::cout << "foo\n"; }
};

template<typename X
class Derived : public X
{
public:
Derived() { this->foo(); }

};

int main()
{
Derived<Base> d;
}



Wenn du oben im Konstruktor von Derived das "this->" wegnimmst, ist der
Code nicht korrekt, weil der Compiler an der Stelle noch nicht weiß, daß
foo() eine Memberfunktion sein soll.
Zumindest neuere Compiler werden den Code nur mit "this->" akzeptieren.


this-> sollte an dieser Stelle nicht notwendig sein:

template<typename X>
class Derived : public X
{
public:
Derived() { X::foo(); }

};

Ich würde fast sagen, dass mir X::foo() besser gefällt. this->foo() ist
dagegen wohl wartbarer.

Christoph Bartoschek

--
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
Heinz Saathoff
Guest





PostPosted: Wed May 31, 2006 12:58 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote

Moin,

Rolf Magnus schrieb...
Quote:
[Beispiel zu dependent names:]
#include <iostream

class Base
{
public:
void foo() { std::cout << "foo\n"; }
};

template<typename X
class Derived : public X
{
public:
Derived() { this->foo(); }

};

int main()
{
Derived<Base> d;
}



Wenn du oben im Konstruktor von Derived das "this->" wegnimmst, ist der Code
nicht korrekt, weil der Compiler an der Stelle noch nicht weiß, daß foo()
eine Memberfunktion sein soll.

Ich hatte das so in Erinnerung, daß templates als 'Codeschablone' erst
zum Zeitpunkt der Instanziierung in dem dann gültigen Kontext übersetzt
werden. Da in Deinem Beispiel Base ein foo enthält, sollte es auch ohne
this gehen. Hier ein modifiziertes Beispiel:

#include <iostream>

class Base {
public:
void foo() { std::cout << "foo\n"; }
};

class HasNoFoo {
};

template<typename X>
class Derived : public X {
public:
Derived() { foo(); }
};

void foo() { std::cout << "global foo\n"; }

int main() {
Derived<Base> d;
Derived<HasNoFoo> nfb; //(1)
}

Als Ausgabe würde ich hier
foo
global foo
erwarten. Falls es zum Zeitpunkt (1) kein globales foo gibt, sollte ein
Compilerfehler die Folge sein.

Wie gesagt, so hatte ich das in Erinnerung.


- Heinz

--
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 May 31, 2006 3:22 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote

Christoph Bartoschek wrote:
Quote:
Rolf Magnus wrote:

Ein Stück Code sagt mehr als tausend Worte:

#include <iostream

class Base
{
public:
void foo() { std::cout << "foo\n"; }
};

template<typename X
class Derived : public X
{
public:
Derived() { this->foo(); }
};

int main()
{
Derived<Base> d;
}

Wenn du oben im Konstruktor von Derived das "this->"
wegnimmst, ist der Code nicht korrekt, weil der Compiler an
der Stelle noch nicht weiß, daß foo() eine Memberfunktion
sein soll. Zumindest neuere Compiler werden den Code nur
mit "this->" akzeptieren.

this-> sollte an dieser Stelle nicht notwendig sein:

Etwas ist aber notwendig.

Quote:
template<typename X
class Derived : public X
{
public:
Derived() { X::foo(); }

};

Ich würde fast sagen, dass mir X::foo() besser gefällt.
this->foo() ist dagegen wohl wartbarer.

Im Constructor haben beide mehr oder weniger dieselbe Wirkung.
In anderen Funktionen dagegen nicht: was passiert, falls foo()
in der Basisklasse virtuell ist?

--
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
Jörg Barfurth
Guest





PostPosted: Thu Jun 01, 2006 8:20 am    Post subject: Re: Warum nicht this->[2] ? Reply with quote

Heinz Saathoff schrieb:

Quote:
Rolf Magnus schrieb...
[gekürzt]
[Beispiel zu dependent names:]

template<typename X
class Derived : public X
{
public:
Derived() { this->foo(); }

};


Wenn du oben im Konstruktor von Derived das "this->" wegnimmst, ist der Code
nicht korrekt, weil der Compiler an der Stelle noch nicht weiß, daß foo()
eine Memberfunktion sein soll.

Ich hatte das so in Erinnerung, daß templates als 'Codeschablone' erst
zum Zeitpunkt der Instanziierung in dem dann gültigen Kontext übersetzt
werden.

So haben viele Compiler das (fälschlich) implementiert. Der Standard
verlangt aber etwas anderes. Der Compiler muss die Namensauflösung in
einem Template in zwei Phasen durchführen (immer noch vereinfacht):

- Namen deren Bedeutung nicht von Templateargumenten abhängt im Kontext
der Templatedefinition auflösen und binden,

- Namen deren Bedeutung von Templateargumenten abhängt im
Instantiierungskontext auflösen.

Erst in letzter Zeit wird das von manchen Compilern weitgehend umgesetzt.

Das ist übrigens auch einer der Gründe warum 'export' von so wenigen
Compilern unterstützt wird - einschließlich solchen, die schon lange die
separate Compilierung von Templates unterstützen (aber eben mit
einfacherer Semantik bei der Namensauflösung).

Quote:
Da in Deinem Beispiel Base ein foo enthält, sollte es auch ohne
this gehen. Hier ein modifiziertes Beispiel:

#include <iostream

class Base {
public:
void foo() { std::cout << "foo\n"; }
};

class HasNoFoo {
};

template<typename X
class Derived : public X {
public:
Derived() { foo(); }

Fehler: foo() nicht bekannt.

Hier bei dir ist foo() ein nicht-abhängiger Name, muss also schon hier
aufgelöst und gebunden werden. Es gibt iirc sogar eine Extraregel, die
sagt dass beim Auflösen unqualifizierter Namen in Klassentemplates
abhängige Basisklassen nicht berücksichtigt werden sollen.

Bei Rolf ist foo() (in this->foo()) ein abhängiger Name und muss
aufgrund der Syntax ein Kassenmember sein. Daher wird in seinem Falle
foo in Base gefunden.

Quote:
};

void foo() { std::cout << "global foo\n"; }

int main() {
Derived<Base> d;
Derived<HasNoFoo> nfb; //(1)
}

Als Ausgabe würde ich hier
foo
global foo
erwarten. Falls es zum Zeitpunkt (1) kein globales foo gibt, sollte ein
Compilerfehler die Folge sein.

Wie gesagt, so hatte ich das in Erinnerung.


So verhalten sich manche Compiler, aber das ist falsch.

Korrekt ist bei deinem Code eine Fehlermeldung und wenn ::foo vor
Derived deklariert wird, dann sollte zweimal "global foo" ausgegeben werden.

Damit vermeidest du auch böse Überraschungen in Fällen wie:

// Aus einer Bibliothek, die du nicht kontrollierst
class SomeLibraryClass
{
// a very internal function
// return value must be deletd eventually
something * foo();
public:
// ...
};

// ...

class MyNoFoo : public SomeLibraryClass
{
// no foo here
};

void bar()
{
Derived< MyNoFoo > d;
}

Was sollte hier passieren, wenn Derived eigentlich das globale foo()
rufen sollte..

- Jörg

--
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
Andre Poenitz
Guest





PostPosted: Mon Jun 12, 2006 10:54 pm    Post subject: Re: Warum nicht this->[2] ? Reply with quote

Jörg Barfurth <usenet05 (AT) barfurth (DOT) de> wrote:
Quote:
So haben viele Compiler das (fälschlich) implementiert. Der Standard
verlangt aber etwas anderes. Der Compiler muss die Namensauflösung in
einem Template in zwei Phasen durchführen (immer noch vereinfacht):

- Namen deren Bedeutung nicht von Templateargumenten abhängt im Kontext
der Templatedefinition auflösen und binden,

- Namen deren Bedeutung von Templateargumenten abhängt im
Instantiierungskontext auflösen.

Erst in letzter Zeit wird das von manchen Compilern weitgehend umgesetzt.

Gibt es eigentlich nachvollziehbare Gruende, warum das so ersonnen
wurde?

Andre'

--
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.