 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
helmut.weil@t-online.de Guest
|
Posted: Tue May 23, 2006 9:33 am Post subject: Warum nicht this->[2] ? |
|
|
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
|
Posted: Tue May 23, 2006 12:21 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Tue May 23, 2006 4:41 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Tue May 23, 2006 8:30 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
<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
|
Posted: Wed May 24, 2006 9:21 am Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Tue May 30, 2006 7:50 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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.
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
|
Posted: Tue May 30, 2006 9:58 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Wed May 31, 2006 12:58 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Wed May 31, 2006 3:22 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Thu Jun 01, 2006 8:20 am Post subject: Re: Warum nicht this->[2] ? |
|
|
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
|
Posted: Mon Jun 12, 2006 10:54 pm Post subject: Re: Warum nicht this->[2] ? |
|
|
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 |
|
 |
|
|
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
|
|