if(...){...} else{...} nicht durch (...)?{...}:{...}; ersetzbar?
-
Anscheinend schon, sonst hätte er ja keine Probleme mit dem Code.
-
Bashar schrieb:
Zuweisungen sind normalerweise Ausdrücke. Ist das beim Builder anders?
Ja, dort gibt es so etwas Lustiges, das sich "properties" nennt. Bei Zugriffen darauf wird verkappt eine entsprechende read/write-Funktion aufgerufen. Und mit so "komplexen" Ausdrücken wie A->Caption=B->Caption="C" kommt er dann nicht mehr klar und der Compiler (und damit dann auch die IDE) quittiert den Dienst mit "Unknown Error #1" (zumindest bei meiner Uralt-Version vom Builder, anscheinend gibt es ja jetzt sogar nach langer Entwicklungszeit eine "richtige" Fehlermeldung).
-
devkid schrieb:
Warum nicht einfach:
LabelABC->Caption = Integer == 1 ? "String1" : "String2";
Weil ich nach 9 Stunden Bildschirm anglotzen einfach nicht daran gedacht habe, dass es ja da noch einen Rückgabewert geben kann... Vielen Dank!
Nanyuki schrieb:
Bashar schrieb:
Zuweisungen sind normalerweise Ausdrücke. Ist das beim Builder anders?
Ja, dort gibt es so etwas Lustiges, das sich "properties" nennt. ...
Ganz genau! Nur dass ich diese "properties" nicht lustig finde...
Irgendwie machen die mir ziemlich oft einen Strich durch die Rechnung!!!
Danke für alle Beiträge.
MfG
-
Bashar schrieb:
Zuweisungen sind normalerweise Ausdrücke. Ist das beim Builder anders?
Nein, ein Ausdruck würde ja irgendwas zurückliefern, ein Ergebnis oder so. Eine Zuweisung tut dies nicht.
-
Powerpaule schrieb:
Nein, ein Ausdruck würde ja irgendwas zurückliefern, ein Ergebnis oder so. Eine Zuweisung tut dies nicht.
In Standard-C++ schon, deshalb fragte ich, ob das etwas Builder-spezifisches ist. Die Antworten dazu haben meine Vermutung bestätigt.
-
Hallo
Auch im Builder liefern normale Zuweisungen ein Ergebnis zurück. Aber bei den VCL-Properties wird die Zuweisung vom Compiler automatisch umgeformt, da in den meisten Fällen für die Property eine Set-Methode aufgerufen wird.
// Aus Edit1->Text = "Test"; // wird vereinfacht dargestellt Edit1->SetText("Test");
Da die SetFunktion aber mit void als Rückgabewert definiert ist, gibt die Zuweisung keinen Wert zurück.
bis bald
akari
-
Hm, ich weiß ja nicht, aber offensichtlich verstehee ich das Problem nicht richtig... Meiner Meinung nach hat Nanyuki schon die richtige Antwort gegeben.
Es gibt tatsächlich Properties in Standard C++? Wußte ich gar nicht.
Das ist auch der Grund, warum das nicht funktioniert, es ist eben keine Zuweisung, sondern ein Funktionsaufruf, zumindest soweit ich das mit den Propertes überblicke.
Ich hab mir mal die Mühe gemacht:
class TTest { public: AnsiString Caption; __property AnsiString propCaption = { read=Caption, write=Caption }; };
Mit dem Ergebnis:
i == 1 ? Test->Caption = "String1" : Test->Caption = "String2"; // funktioniert i == 1 ? Test->propCaption = "String1" : Test->Caption = "String2"; // funktioniert NICHT!
Insofern ist die Fehlermeldung, in meinen Augen, gerechtfertigt. Wo mache ich denn da jetzt den Denkfehler?
-
akari schrieb:
Da die SetFunktion aber mit void als Rückgabewert definiert ist, gibt die Zuweisung keinen Wert zurück.
Das kann nicht der Grund sein, da ein void-Funktionsaufruf ebenfalls ein Ausdruck (mit dem Typ void) ist und selbstverständlich in ?: verwendet werden darf.
-
Mal als Diskussionsgrundlage
:
BDS2006-Hilfe schrieb:
Bedingungsoperator
Syntax
[C++]logischer OR-Ausdruck ?: Bedingungs-AusdruckBemerkungen
Der Bedingungsoperator ?: ist ein dreiteiliger Operator.
Im Ausdruck E1 ? E2 : E3 wird E1 zuerst ausgewertet. Wenn sein Wert true ist, so wird danach E2 ausgewertet und E3 ignoriert. Wenn E1 false ergibt, so wird E3 ausgewertet und E2 ignoriert.Das Ergebnis von E1 ? E2 : E3 ist entweder der Wert von E2 oder von E3, abhängig davon, welcher dieser Werte ausgewertet wurde.
E1 muss ein Ausdruck von skalarem Typ sein. E2 und E3 müssen einer der folgenden Regeln entsprechen:
1. Beide sind arithmetische Typen. In diesem Fall unterliegen E2 und E3 den arithmetischen Standardkonvertierungen und das Ergebnis entspricht dem üblichen Ergebnistyp dieser Konvertierungen.
2. Beide Operanden sind kompatible Struktur- oder Varianten-Typen. Das Ergebnis ist vom Struktur- oder Varianten-Typ von E2 und E3.
3. Beide Operanden sind vom Typ void. Das Ergebnis ist vom Typ void.
4. Beide Operanden sind Zeiger auf qualifizierte oder unqualifizierte kompatible Typen. Als Ergebnis erhalten Sie einen Typ, der ein Zeiger auf einen Typ ist, der alle Typqualifizierer der Typen besitzt, auf die beide Operanden zeigen.
5. Einer der Operanden ist ein Zeiger, der andere eine Nullzeiger-Konstante. Als Ergebnis erhalten Sie einen Typ, der ein Zeiger auf einen Typ ist, der alle Typqualifizierer der Typen besitzt, auf die beide Operanden zeigen.
6. Ein Operand ist ein Zeiger auf ein Objekt oder auf einen unvollständigen Typ, und der jeweils andere ist ein Zeiger auf eine qualifizierte oder unqualifizierte Version des Typs void. Als Ergebnis erhalten Sie einee Nullzeiger-Konstante auf den Operanden void.Die Hilfe des RAD-Studio 2009 liefert eine identische Beschreibung und auch die Hilfe des C++Builder 3 unterscheidet sich inhaltlich nicht.
-
Joe_M. schrieb:
Hm, ich weiß ja nicht, aber offensichtlich verstehee ich das Problem nicht richtig... Meiner Meinung nach hat Nanyuki schon die richtige Antwort gegeben.
Hat er auch. Property-Zuweisungen sind offensichtlich keine Ausdrücke. Der Thread hätte an der Stelle zuende sein können
Es gibt tatsächlich Properties in Standard C++?
Nein.
Wo mache ich denn da jetzt den Denkfehler?
Nirgends
-
Den Grund, den akari genannt hat, ist schon richtig.
Da Properties intern eben read/write-Methoden (bzw. Getter/Setter) aufrufen, müßte bei einer Zuweisung eigentlich der entsprechende Wert zurückgegeben werden. Dann aber müßte der Compiler implizit wiederum die read(Getter)-Methode aufrufen. Da aber Properties auch write-only sein können, gäbe es dann wiederum Ausnahmen (und es ist nicht sichergestellt, daß der Getter und der Setter zusammenpassen). Daher verbietet der Compiler jedliche komplexere Ausdrücke als eine "einfache Zuweisung".
So wird z.B. auchstring s = Label1->Caption = Label2->Caption;
mit einer (derselben?) Fehlermeldung nicht vom Compiler akzeptiert.
bashar, du hast zwar insofern Recht, daß auch void innerhalb des triären Operators ?: normalerweise akzeptiert wird, jedoch scheint der Compiler (bzw. die Borland-Entwickler) diesen Spezialfall ebenfalls als komplexe Anweisung anzusehen (denn der eigentlich erwartete Rückgabewert wäre in dem Beispiel ja AnsiString).
Daher ist
LabelABC->Caption = Integer == 1 ? "String1" : "String2";
die einzige Möglichkeit...
-
Th69 schrieb:
... So wird z.B. auch
string s = Label1->Caption = Label2->Caption;
mit einer (derselben?) Fehlermeldung nicht vom Compiler akzeptiert. ...
Ja, mit genau derselben Fehlermeldung!