Hallo,
ich frage mich die ganze Zeit schon, warum der typeof-operator (und der
zukünftige decltype-operator) nicht mit non-static data members einer
Klasse zusammen arbeitet.
Beispiel:
1
classA{
2
intB;
3
typeof(B);// Error, wegen Zugriff auf nicht
4
// statisches Klassenattribut
5
}
Dabei spielt es doch gar keine Rolle ob B statisch oder nicht statisch
ist... B hat einen Datentypen und den will ich mit typeof in diesem
(zugegebenermaßen hier etwas sinnlosen) Zusammenhang ermitteln.
Kann mir jemand erklären warum dies nicht funktioniert? Mir fällt
einfach keine sinnvolle Begründung dafür ein, aber vielleicht weiß ja
ein GCC Spezialist mehr darüber...?
Ich danke schon einmal im Voraus,
Netbandit
Hallo,
typeof wird ja zur Compilierzeit ausgewertet. Für die Laufzeitauswertung
gibt es ja glaube ich typeid oder so.
Im Grunde dürfte typeof für C++ und C gleich arbeiten. Beispiel:
1
voidmain(void){
2
intA;
3
typeof(A)B;
4
5
while(1){
6
}
7
return;
8
}
In diesem Beispiel ist B vom Typ int. Genauso klappt das auch bei C++
mit Objekten und Klassenattributen bzw. mit statischen
Klassenattributen:
1
classCA{
2
inti;
3
}
4
5
voidmain(void){
6
CAA;
7
typeof(A.i)B;
8
9
while(1){
10
}
11
return;
12
}
Hier ist B dann auch vom Typ integer. Leider brauche ich halt immer ein
Objekt von der Klasse um typeof anwenden zu können oder aber i muss ein
statischen Klassenattribut sein. Ich verstehe doch nicht warum. Typeof
wird zur Compilierzeit ausgewertet und um den Typ zu ermitteln ist es
doch völlig unerheblich ob die Variable im Form eines Objektes oder im
Form eines statischen Attributes schon Speicher belegt oder nicht, ich
will ja nur ihren Datentypen wissen.
In C++ scheint keine Syntax vorgesehen zu sein, mit der ohne die
Benutzung einer Instanz direkt auf ein nichtstatisches Element einer
Klasse zuzugriffen werden kann.
Normalerweise ist es ja auch wenig sinnvoll auf etwas zuzugreifen, was
gar nicht existiert. Einen Sonderfall stellen die Operatoren typeof
und sizeof dar, da diese nicht das Element selbst, sondern nur dessen
Eigenschaften (Typ bzw. Größe) kennen müssen. Aber nur für diese beiden
Operatoren wollten die C++-Entwickler wohl kein eigenes Sprachkonstrukt
definieren.
Wenn innerhalb der Klassendeklaration von A (aber außerhalb der
Definition von Elementfunktionen) der nichtglobale Indentifier B
auftaucht, ist B nichts anderes als die Abkürzung für A::B, und A::B ist
nun einmal die Syntax für den Zugriff auf ein statisches Datenelement
der Klasse.
Immerhin gibt einen Hack, mit dem man das Problem zumindest teilweise
umgehen kann: Man definiert eine Pseudoinstanz von A an der Adresse 0
(oder sonstwo). Da auf die Instanz nicht wirklich zugegriffen wird, ist
das in Ordnung, wenn auch unschön:
1
typeof((A*)0)->B
bzw.
1
sizeof((A*)0)->B
Der Hack funktioniert aber nur außerhalb der Klassendeklaration von A.
Versucht man, ihn innerhalb der Klassendeklaration anzuwenden, meckert
der GCC schon wieder:
1
error: invalid use of incomplete type ‘class A’
was ebenfalls schwer nachzuvollziehen ist, da er zur Bestimmung der
Eigenschaften von B ja nicht die gesamte Klasse kennen muss.
Wahrscheinlich hängt das damit zusammen, dass der Compiler erst dann mit
Instanzen umgehen kann, wenn die zugehörige Klasse als Ganzes bekannt
ist.
Das sind bei weitem nicht die einzigen Fälle, wo die Sprachdefinition
von C++ etwas krumm ist. Java und C# sind in dieser Hinsicht sicher
sauberer definiert (man hat ja hoffentlich dazugelernt).Trotzdem ist C++
in meinen Augen nach wie vor die beste Vereinigung der C-Philosophie
(Hardwarenähe, Determinismus usw.) und der objektorientierten
Programmierung.
Diese, meiner Meinung nach, geniale Lösung kommt von Mathias Gaunard aus
der Mailingliste vom GNU C++ und läuft bei mir inzwischen auch ganz gut.
Es gibt halt manchmal schon Fälle wo man den Datentyp auf dieser Art und
Weise bestimmen möchte, da es nicht mehr so leicht nachvollziehbar ist
welcher Datentyp zu einem Klassenmember gehört oder nicht.
Du vermutest ja, dass es sich bei der Einschränkung des typeof bzw.
sizeof Operators auf nicht statische oder als Objekt vorhandene
Elemente, eher um zufälliges Versäumnis beim GCC handelt. Immerhin ist
ja der typeof-Operator eine Eigenheit des GCCs selbst, ok da kann ich
mir das schon vorstellen, das man damals einfach nicht daran gedacht
hat, dass man den in diesem Kontext verwenden möchte. Was ich aber nicht
nachvollziehen kann ist, dass die gleiche Einschränkung offensichtlich
auch beim im C++09-Standard geplanten Operator decltype gelten soll.
Immerhin hat man sich hier hingesetzt und sich Gedanken dazu gemacht,
wie dieser zu verwenden sei. Daher gehe ich davon aus, dass es einen
guten Grund gibt, ihn nicht so zu verwenden, ansonsten würde doch
absolut nichts dagegen sprechen ihn entsprechend zu definieren (wenn man
eh schon dabei ist).
> Diese, meiner Meinung nach, geniale Lösung kommt von Mathias Gaunard> aus der Mailingliste vom GNU C++ und läuft bei mir inzwischen auch> ganz gut.
Manomann, diese Lösung hat's wirklich in sich! Auf die Idee mit den
Elementzeigern bin ich auch noch gekommen, aber diese alleine bringen ja
nicht viel, weil man für deren Dereferenzierung wieder eine Instanz
braucht. Die Elementzeiger aber mit einer über zwei unterschiedliche
Templates deklarierten Hilfsstruktur zu kombinieren, darauf muss man
erst einmal kommen :)
> Daher gehe ich davon aus, dass es einen guten Grund gibt, ihn nicht so> zu verwenden, ansonsten würde doch absolut nichts dagegen sprechen ihn> entsprechend zu definieren (wenn man eh schon dabei ist).
Vielleicht ist der Grund ja der, dass das Problem ja ganz einfach
mittels Templates umgangen werden kann ;-)
yalu wrote:
> Vielleicht ist der Grund ja der, dass das Problem ja ganz einfach> mittels Templates umgangen werden kann ;-)
Ach so, du meinst also nach dem Motto: "Warum einfach wenn es auch
kompliziert klappt..."
Hehe, daran hab ich noch gar nicht gedacht ;)
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.