Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Template-bastelei

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 ] > 2 < [ 3 ] [ 4 ]
010
14.08.2003, 14:52 Uhr
0xdeadbeef
Gott
(Operator)



Zitat:
virtual postete

Was soll denn nun an f() fübergeben werden? - Folgt man der Implementation


An f wird nichts übergeben, das ist ja gerade der Trick daran. Die Default-Parameter werden ja überhaupt erst gebraucht, wenn nichts übergeben wurde - und dann darf sich f die fehlenden Parameter selbst auffüllen, und das geschieht natürlich auch im Kontext von f. Ich nehm grad nochmal das her, was ich oben auseinandergepfriemelt habe:

C++:
f(X *p = this) { }
//qäre äquivalent zu
f() { f(this); }
f(X *p) { }


Wie du siehst, wird das this aus dem Kontext von f ausgewertet, und genau das ist die Idee dahinter. Nichts anderes passiert ja bei Default-Parametern, wie du mit deinem global-/local-pointer-Beispiel eindrucksvoll gezeigt hast - nicht etwa das ptr aus f() wird ausgewertet, sondern das aus dem Kontext von g(). Alles andere würde auch keinen Sinn machen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
14.08.2003, 15:24 Uhr
virtual
Sexiest Bit alive
(Operator)


Ich glaube, wir reden wirklich ganz erheblich aneinander vorbei. Deshalb nochmal die Zusammenfassung meiner Gedanken:

1. Die Bindung der Default parameter geschieht zum Zeitpunkt der Deklaration. Daher müssen die verwendeten Parameter bereits bekannt sein. Insbesondere nicht deklararierte Variablen und this können somit nicht als Defaultparameter verwendet werden, weil zu this immer eine Instanz gehört, die es zum Deklarationszeitpunkt nicht gibt/geben kann.

2. Löst man die unter (1) genannte Regel auf und sagt: Okay, mir ist egal, was zum Zeitpunkt der Deklaration gegeben ist, dann muß logischerweise die Bindung kontextabhängig sein. Entweder ganz, oder Teilweise.
Damit läuft man genau in die Probleme, die ich zuvor nannte. Insbesondere wäre es nicht consistent:

C++:
struct X
{
     void f(X* x=this);
     void g(X* x) { x->f(); }; //! Hier!
}

...
X y;
y.g();


Eigentlich dürfte nie f(x) aufgerufen werden, weil ja in g das this auf das y zeigt, dh insbesondere der Gedanken gang:

C++:
f(X* = this) { ... };


sei gleichbedeutend mit

C++:
f() { f(this); };
f(X*) { ... };


ist hoch problematisch, weil er unterstellt, daß die parameter zusammengesucht werden, wenn f schon aufgreufen wurde. Dem ist ja nicht so. Die Parameter werden davor zusammengesucht. Also im g - da, wo this auf y zeigt.

Wenn man sich einfach mal vergegenwärtigt, daß this eine lokale Variable ist, dh nur innerhalb einer Methode gültig ist, dann würde das konsequent zu Ende gedacht genau auf das Problem zulaufen, welches ich im local/global ptr aufgezeigt habe.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 14.08.2003 um 15:29 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
14.08.2003, 15:50 Uhr
virtual
Sexiest Bit alive
(Operator)


Aber angenommen, du kommst mit Deinem Vorschlag bei der ISO durch, das in deinem Sinne zu ändern, dann kannst Du ja auch gleich noch mit fordern, daß
this nicht mehr vom Type Klasse * const sondern nur noch Klasse * ist. Das würde ähnlich geile Möglichkeiten eröffnen...

scnr
--
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
013
14.08.2003, 15:52 Uhr
0xdeadbeef
Gott
(Operator)


Das es im Moment nicht so ist, dass man this im Default-Parameter verwenden könnte, ist mir inzwischen klar. Von daher lasse ich Regel 1 mal außen vor. Man könnte es aber so drehen, dass es hinhaut, und zwar konsistent. Folgendes: Wenn du schreibst

C++:
struct X {
  void f(X* x = this) { }
  void g() { x->f(); }
};

Dann hieße das nach meinem Gedankengang aufgesplittet:

C++:
struct X {
  void f() { f(this); }
  void f(X* x) { }
  void g() { x->f(); }
};

M.a.W. this wird erst in f() ausgewertet, und das ist konsistent mit dem Rest der Sprache. Nehmen wir zur Verdeutlichung noch mal dein Beispiel von vorhin her:

C++:
const char *ptr = "global";
const char *g(const char *p = ptr) { return p; }
const char *f() {
  const char *ptr = "local";
  return g();
}
int main() { std::cout << f() << std::endl; }

In diesem Fall wird ja beim Aufruf von f auch nicht implizit das in f() gültige ptr an g weitergegeben, sondern das genommen, was im Scope von g gültig ist. Die Default-Parameter würden also erst nach dem Aufruf der Funktion gebunden.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
14.08.2003, 16:18 Uhr
virtual
Sexiest Bit alive
(Operator)


@beefy:
this Ist in g und f etwas unterschiedliches, dh eine lokale Variable, die nur innerhalb der jeweiligen Funktion eine Bedeutiung hat. Ich finde, daß man dann mit der gleichen Berechtigung sowas schreiben dürfte:

C++:
const char *ptr = "irgendwas";
const char *g(const char *p = ptr) { // mit ptr ist die lokale Variable gemeint, welch Zufall ;)
  const char *ptr = "global";
return p;
}
const char *f() {
  const char *ptr = "local";
  return g();
}
int main() { std::cout << f() << std::endl; }


und es kommt nicht etwa "irgendwas" raus, sondern "global". Denn es ist ja eher Deine Faulheit, die dich dazu bringt, dem this gegenüber anderen lokalen Variablen eine Sonderstellung einräumen zu wollen. Wir sind also genau wieder bei den Punkt 10 Posts zuvor: Wenn die klare Regel aufgelöst wird, dann müssen Ausnahmen geschaffen werden. Und ich danke der ISO, daß sie es nicht getan hat.

Daß man Sonderregelungen machen kann, schließe ich nicht aus, aber ich bin in diesem Fall extrem dagegen und behaupte auch, daß diese Regel die Sprache einfacher macht und nicht schwerer.
--
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
015
14.08.2003, 16:22 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat:
0xdeadbeef postete
M.a.W. this wird erst in f() ausgewertet, und das ist konsistent mit dem Rest der Sprache.

Nee, das wäre nicht konsistent: Parameter werden nun mal erst auf den Stack gelegt und dann wird die Funktion aufgerufen. this ist ein zeiger auf X. Nicht mehr, nicht weniger. Was Du willst, ist f aufrufen und implicit im parameterstack rumpfuschen und aus dem y ein x machen.
--
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
016
14.08.2003, 16:38 Uhr
0xdeadbeef
Gott
(Operator)


Wenn dus auf den Stack beziehst - this im Kontext von f ist gerade noch rechtzeitig bekannt, um nicht rumpfuschen zu müssen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
14.08.2003, 17:57 Uhr
virtual
Sexiest Bit alive
(Operator)


Ach ja, und dann hast Du noch weitere Ausnahmeregelungen:

C++:
struct X
{
   X(X* = this;) { .. } // ctor - autsch!
};


oder auch nett:

C++:
class A {};
class B: public A { };
class C: public A { };
class D: public C, public B
{
   void f(A* = this ) { } // welche this (also A*) hätten sie denn gerne? - autsch!
}


Was ich sagen will:
Du gehts hin und sagst, "lassen wir mal Regel 1 beiseite". Okay, laß uns dann mal überlegen, welche Auswirkungen das hätte, wo man überall rumflicken müßte. Ich bin mir sicher, daß ich - wenn ich genug Zeit finde - dir noch ein paar weitere Situationen liefern kann.
Der Punkt ist doch einfach der: this ist ne lokale Variable, die sich von anderen Variablen dadurch unterscheidet, daß sie ziemlich häufig implizit da ist. Nicht mehr und nicht weniger. Wenn du es schick findest, this in Deinem Sinne als DefaultArgument verwenden zu können, beantworte mir folgende Fragen:

1. Mit welcher begründung darf ich das nicht mit anderen lokalen variablen genauso machen? Warum ist es nicht willkürlich, this als Defaultparameter zu übergeben, andere Lokale Variablen eben nicht?

2. Die beiden obigen Beispiele sind ein kleiner Vorgschmack, was passieren kann, wenn Du solche Sachen zu lässt. Wie willst Du das in den Griff bekommen, ohne weitere Ausnahme Regelungen zu finden?

3. Was macht Deine Interpretation des Default Parameter "this" sinnvoller als folgende: Wird this als default argument übergeben, expandiert es zur Addresse des Aufrufenden Objekts. Sollte der Aufruf aus keinen Zuweisungskompatiblen Objekt erfolgen, meckert der Compiler und läßt es nicht zu?
--
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
018
14.08.2003, 18:16 Uhr
0xdeadbeef
Gott
(Operator)


Das sind allerdings alles Sonderregelungen, die du so oder so hast. Das erste geht schon nicht, weil this ein const X* ist, und er deswegen den Cast nicht rafft. Das andere wäre nach meinem Vorschlag ebenso zulässig wie

C++:
struct A {
  const A *me;
  A() : me(this) {}
};


Und was das zweite angeht - versuch mal das hier:

C++:
struct A {
  void foo() { }
};

struct B : public A { };
struct C : public A { };

struct D: public B, public C { };

D d;

d.foo(); //ambiguous call. Oops.


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
14.08.2003, 18:21 Uhr
0xdeadbeef
Gott
(Operator)


Zu deinen Fragen:

1. this als Default-Parameter bedeutet meiner Idee nach, dass this aus dem Scope der aufgerufenen, nicht der aufrufenden Methode genommen wird. Das geht natürlich auch mit anderen lokalen Variablen der aufgerufenen Methode, sofern diese bei der Deklaration schon feststehen. Beispiel:

C++:
class A {
  int i;
public:
  void f(int = i);
};



2. Mir ist keine wirkliche Ausnahme bisher auf- oder eingefallen.

3. Eben dass das Objekt nicht unbedingt kompatibel ist. Es geht um die Adresse des Objekts, dessen Methode aufgerufen wird.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ] [ 4 ]     [ 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: