 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Jan Gosmann Guest
|
Posted: Tue Sep 12, 2006 9:18 pm Post subject: Wie kann ich einen Iterator in einer template-Klasse erstell |
|
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hallo,
ich schreibe gerade eine template-Klasse und habe das Problem, dass sich
mein Compiler (g++) über die Zeile, in der ich Versuche den Iterator zu
erstellen, mit folgender Meldung beschwert: "error: expected ?;? before
?bar?". Hier ist der Code:
template <class type> Foo
{
list<type>::iterator bar;
}
Wenn ich type durch int ersetze geht es übrigens. Wäre nett, wenn mir
wer helfen könnte.
MfG, Jan Gosmann
- --
E-Mail: blubb@hyper-world.de
Homepage: www.hyper-world.de
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFFBt3LffrSAKqtmpcRAuFWAJ99jNNc+Kzb6ylksB+UttJkcr7VDwCeIwuq
XkmflRb/k9nShvECzpmHkQ4=
=Tz2p
-----END PGP SIGNATURE----- |
|
| Back to top |
|
 |
Hubert Schmid Guest
|
Posted: Wed Sep 13, 2006 1:34 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jan Gosmann <blubb@hyper-world.de> writes:
| Quote: | template <class type> Foo
{
list<type>::iterator bar;
}
|
Vermutlich fehlt hier ein 'struct', ein 'typename' und ein ';':
template <class type> struct Foo
{
typename list<type>::iterator bar;
};
--
Hubert Schmid - http://www.z42.de |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Wed Sep 13, 2006 2:14 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jan Gosmann <blubb@hyper-world.de> writes:
| Quote: | ich schreibe gerade eine template-Klasse und habe das Problem, dass
sich mein Compiler (g++) über die Zeile, in der ich Versuche den
Iterator zu erstellen, mit folgender Meldung beschwert: "error:
expected ?;? before ?bar?". Hier ist der Code:
template <class type> Foo
{
list<type>::iterator bar;
|
Das Problem ist, dass der Compiler hier nicht wissen kann, was der
Name iterator bedeutet. Es könnte ja später eine Spezialisierung von
list daherkommen, welche den Namen zu etwas anderem deklariert als das
Basistemplate (oder den Namen gar nicht deklariert).
Der Compiler muss deshalb eine Annahme treffen, und die Regel für
diese Annahme lautet: wenn der Programmierer nicht ausdrücklich
schreibt, dass es sich um den Namen eines Typs handelt, ist es keiner.
typename list<type>::iterator bar;
sollte funktionieren. |
|
| Back to top |
|
 |
Marcel Müller Guest
|
Posted: Wed Sep 13, 2006 2:25 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jan Gosmann wrote:
| Quote: | template <class type> Foo
{
list<type>::iterator bar;
|
Da fehlt ein 'typename'.
typename list<type>::iterator bar;
Der Parser kann sonst nicht Wissen, ob aus list<type>::iterator später
eine Datentyp oder ein Element wird. Theoretisch könnte sich das für
verschiedene 'type' sogar unterscheiden.
Marcel |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Wed Sep 13, 2006 3:11 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jan Gosmann wrote:
| Quote: | ich schreibe gerade eine template-Klasse und habe das Problem, dass sich
mein Compiler (g++) über die Zeile, in der ich Versuche den Iterator zu
erstellen, mit folgender Meldung beschwert: "error: expected ?;? before
?bar?". Hier ist der Code:
template <class type> Foo
{
list<type>::iterator bar;
}
Wenn ich type durch int ersetze geht es übrigens. Wäre nett, wenn mir
wer helfen könnte.
|
Das Problem ist, daß du hier einen vom Template-Argument abhänigen Typ hast.
Der Compiler weiß aber nicht, ob list<type>::iterator ein Typ oder eine
Variable ist. Deshalb mußt du ihm das explizit sagen:
template <class type> Foo
{
typename list<type>::iterator bar;
} |
|
| Back to top |
|
 |
Jan Gosmann Guest
|
Posted: Wed Sep 13, 2006 5:45 pm Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hubert Schmid schrieb:
| Quote: | Vermutlich fehlt hier ein 'struct', ein 'typename' und ein ';':
template <class type> struct Foo
{
typename list<type>::iterator bar;
};
|
Das mit dem 'struct' und dem ';' ist mir beim Schreiben des Beispiels
passiert (ich hab's nicht direkt aus meinem Programm kopiert) und war
zudem etwas in Eile...
Es lag dann am fehlenden 'typename'. Wieder mal was dazu gelernt Danke!
- --
E-Mail: blubb@hyper-world.de
Homepage: www.hyper-world.de
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFFB/1bffrSAKqtmpcRAug1AJ44tDOJCHN1clrrcqH85bHstwRH1ACePwZW
Qm6FXNjKTWUZjkxXTPJLt5Y=
=mVu2
-----END PGP SIGNATURE----- |
|
| Back to top |
|
 |
Jens Müller Guest
|
Posted: Wed Oct 04, 2006 9:03 pm Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Marcel Müller schrieb:
| Quote: | Jan Gosmann wrote:
template <class type> Foo
{
list<type>::iterator bar;
Da fehlt ein 'typename'.
typename list<type>::iterator bar;
Der Parser kann sonst nicht Wissen, ob aus list<type>::iterator später
eine Datentyp oder ein Element wird. Theoretisch könnte sich das für
verschiedene 'type' sogar unterscheiden.
|
Nunja, bei einem Nicht-Template-Member kann der _Parser_ das auch nicht
wissen, das wird schon ein bißchen später geprüft. |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Thu Oct 05, 2006 1:59 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jens Müller wrote:
| Quote: | Marcel Müller schrieb:
typename list<type>::iterator bar;
Der Parser kann sonst nicht Wissen, ob aus list<type>::iterator später
eine Datentyp oder ein Element wird. Theoretisch könnte sich das für
verschiedene 'type' sogar unterscheiden.
Nunja, bei einem Nicht-Template-Member kann der _Parser_ das auch nicht
wissen, das wird schon ein bißchen später geprüft.
|
Der Parser muss schon wissen, ob es sich bei einem Bezeichner um
einen Typnamen handelt - egal, ob der Bezeichner nur 'foo' oder
'list<T>::iterator' heißt. '(foo)+a*b' bedeutet was komplett anderes
wenn foo ein Typ ist, als wenn es ein Objekt ist. 'foo(*x);' führt
einen neuen Namen 'x' ein wenn foo ein Typ ist, referenziert einen
existierenden Namen 'x' wenn foo ein Objekt bzw. eine Funktion ist.
Deswegen ist C++ ja so schwierig zu parsen.
Stefan |
|
| Back to top |
|
 |
Jens Müller Guest
|
Posted: Thu Oct 05, 2006 3:56 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Stefan Reuther schrieb:
| Quote: | Jens Müller wrote:
Marcel Müller schrieb:
typename list<type>::iterator bar;
Der Parser kann sonst nicht Wissen, ob aus list<type>::iterator später
eine Datentyp oder ein Element wird. Theoretisch könnte sich das für
verschiedene 'type' sogar unterscheiden.
Nunja, bei einem Nicht-Template-Member kann der _Parser_ das auch nicht
wissen, das wird schon ein bißchen später geprüft.
Der Parser muss schon wissen, ob es sich bei einem Bezeichner um
einen Typnamen handelt - egal, ob der Bezeichner nur 'foo' oder
'list<T>::iterator' heißt. '(foo)+a*b' bedeutet was komplett anderes
wenn foo ein Typ ist, als wenn es ein Objekt ist.
|
Eben. Der nicht kontextfreie Teil der Syntax wird im Übersetzerbau
üblicherweise als statische Semantik bezeichnet. |
|
| Back to top |
|
 |
Hubert Schmid Guest
|
Posted: Thu Oct 05, 2006 11:37 pm Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jens Müller <usenet-01-2006 (AT) tessarakt (DOT) de> writes:
| Quote: | Stefan Reuther schrieb:
Jens Müller wrote:
Marcel Müller schrieb:
typename list<type>::iterator bar;
Der Parser kann sonst nicht Wissen, ob aus list<type>::iterator
später eine Datentyp oder ein Element wird. Theoretisch könnte
sich das für verschiedene 'type' sogar unterscheiden.
Nunja, bei einem Nicht-Template-Member kann der _Parser_ das auch
nicht wissen, das wird schon ein bißchen später geprüft.
Der Parser muss schon wissen, ob es sich bei einem Bezeichner um
einen Typnamen handelt - egal, ob der Bezeichner nur 'foo' oder
'list<T>::iterator' heißt. '(foo)+a*b' bedeutet was komplett
anderes wenn foo ein Typ ist, als wenn es ein Objekt ist.
Eben. Der nicht kontextfreie Teil der Syntax wird im Übersetzerbau
üblicherweise als statische Semantik bezeichnet.
|
Es geht darum, dass der Übersetzer *nach* der Analyse der statischen
Semantik feststellen kann, ob es sich um einen Typ handelt. Das geht
ohne typename nicht.
Betrachte beispielsweise die Übersetzungseinheit, die nur aus der
folgenden Zeile besteht. Ist t: hier ein Typ oder eine statische
Member-Funktion?
export template <class t> t f() { return t: (); }
--
Hubert Schmid - http://www.z42.de |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Fri Oct 06, 2006 2:39 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jens Müller wrote:
| Quote: | Stefan Reuther schrieb:
Jens Müller wrote:
[typename]
Nunja, bei einem Nicht-Template-Member kann der _Parser_ das auch nicht
wissen, das wird schon ein bißchen später geprüft.
Der Parser muss schon wissen, ob es sich bei einem Bezeichner um
einen Typnamen handelt - egal, ob der Bezeichner nur 'foo' oder
'list<T>::iterator' heißt. '(foo)+a*b' bedeutet was komplett anderes
wenn foo ein Typ ist, als wenn es ein Objekt ist.
Eben. Der nicht kontextfreie Teil der Syntax wird im Übersetzerbau
üblicherweise als statische Semantik bezeichnet.
|
Ich versteh jetzt nicht genau, was du mir damit sagen willst.
Der Parser muss wissen, ob 'foo' ein Typ ist. Das bekommt er von z.B.
der Symboltabelle gesagt (oder meintest du das mit "später"? Das ist
dann IMHO missverständlich, da es zwar nach dem Parsen der Definition
von 'foo' passiert, aber natürlich bevor ein Konstrukt wie 'foo*i;'
geparst wird). Bei 'list<T>::iterator' weiß auch die Symboltabelle nicht
weiter, und da muss man ihm halt mit 'typename' auf die Sprünge helfen.
Stefan |
|
| Back to top |
|
 |
Jens Müller Guest
|
Posted: Fri Oct 06, 2006 9:11 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Stefan Reuther schrieb:
| Quote: | Der Parser muss schon wissen, ob es sich bei einem Bezeichner um
einen Typnamen handelt - egal, ob der Bezeichner nur 'foo' oder
'list<T>::iterator' heißt. '(foo)+a*b' bedeutet was komplett anderes
wenn foo ein Typ ist, als wenn es ein Objekt ist.
Eben. Der nicht kontextfreie Teil der Syntax wird im Übersetzerbau
üblicherweise als statische Semantik bezeichnet.
Ich versteh jetzt nicht genau, was du mir damit sagen willst.
Der Parser muss wissen, ob 'foo' ein Typ ist. Das bekommt er von z.B.
der Symboltabelle gesagt
|
Nein, von der Definitionstabelle.
| Quote: | (oder meintest du das mit "später"? Das ist
dann IMHO missverständlich, da es zwar nach dem Parsen der Definition
von 'foo' passiert, aber natürlich bevor ein Konstrukt wie 'foo*i;'
geparst wird). Bei 'list<T>::iterator' weiß auch die Symboltabelle nicht
weiter, und da muss man ihm halt mit 'typename' auf die Sprünge helfen.
|
Die Symboltabelle weiß nur, daß "list" das gleiche Symbol ist wie "list"
und "iterator" das gleiche Symbol wie "iterator".
Was zu einer Verwendung die gültige Definition ist, weiß die
Definitionstabelle. Und die wird nach der Zerteilung angelegt. |
|
| Back to top |
|
 |
Jens Müller Guest
|
Posted: Fri Oct 06, 2006 9:11 am Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Hubert Schmid schrieb:
| Quote: | Es geht darum, dass der Übersetzer *nach* der Analyse der statischen
Semantik feststellen kann, ob es sich um einen Typ handelt. Das geht
ohne typename nicht.
|
Ich weiß. Aber bei der Zerteilung kann er es auf jeden Fall noch nicht
feststellen. Die kommt nämlich vor der semantischen Analyse. |
|
| Back to top |
|
 |
Jens Müller Guest
|
Posted: Fri Oct 06, 2006 5:07 pm Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Stefan Reuther schrieb:
| Quote: | Der Parser muss wissen, ob 'foo' ein Typ ist.
|
Vielleicht nochmal anders:
Nein, der Zerteiler _weiß_, daß 'foo' ein Typ sein muß. Ob foo wirklich
ein Typ ist, wird dann in der semantischen Analyse festgestellt ist.
Bei Templates könnte man das dann ohne typename erst bei der
Instanziierung feststellen. Da man das nicht will, weil man gewisse
Aspekte der Semantik auch unabhängig von einer konkreten Instanziierung
prüfen können will, verlangt man typename. |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Fri Oct 06, 2006 9:26 pm Post subject: Re: Wie kann ich einen Iterator in einer template-Klasse ers |
|
|
Jens Müller wrote:
| Quote: | Stefan Reuther schrieb:
Der Parser muss wissen, ob 'foo' ein Typ ist.
Vielleicht nochmal anders:
Nein, der Zerteiler _weiß_, daß 'foo' ein Typ sein muß. Ob foo wirklich
ein Typ ist, wird dann in der semantischen Analyse festgestellt ist.
|
Ich weiß jetzt nicht, was du mit Zerteiler meinst. Falls du den Parser
meinst, der aus einem Tokenstrom ermittelt, zu welcher Grammatik-
produktion ein Codeschnipsel gehört: genau das parsen, translation phase
7, ist in C++ ohne Feedback von der Symboltabelle (das ist bei mir das
Etwas, welches weiß, dass "::foo" eine int-Variable bezeichnet usw.) zum
Parser nicht sinnvoll möglich.
Nimm das Programmschnipselchen
(foo)+a*b
Das kann dem Ausdruck
static_cast<foo>(+a) * b
entsprechen oder dem Ausdruck
foo + (a*b)
also zwei Ausdrücke vollkommen verschiedener Struktur.
Natürlich kann man, mit endlichem Aufwand, statt eines Parse-Baumes eine
Menge Parse-Bäume erstellen und dann in der nachgeschalteten Semantik-
Stufe die nicht mehr gültigen verwerfen. Das braucht aber leicht
exponenziellen Speicher (für jedes geklammerte Wort in einem Ausdruck
verdoppelt sich die Anzahl Möglichkeiten). Das will man aber nicht
(deswegen gibt's auch so Regeln wie den point-of-declaration, ab dem ein
Name bekannt ist -- ohne das bräuchte man, wie in Java, keine Vorwärts-
Deklarationen).
| Quote: | Bei Templates könnte man das dann ohne typename erst bei der
Instanziierung feststellen. Da man das nicht will, weil man gewisse
Aspekte der Semantik auch unabhängig von einer konkreten Instanziierung
prüfen können will, verlangt man typename.
|
Eben. Ohne typename könnte man nur den Tokenstrom speichern und bei der
Instanziierung parsen. Dann bekäme man auf einmal beim Aufruf einer
Template-Funktion Syntax-Fehler.
Stefan |
|
| 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
|
|