Template-Syntax

Hallo,

bisher dachte ich immer, es sei nicht schwierig die Syntax einer Programmiersprache zu erlernen, nur die Semantik sei manchmal kompliziert…

Jetzt habe ich folgende Problem: ich schreibe eine Klasse DreierVektor (ja, ich weiss, sowas gibts als fertige Bibliothek, ich schreibe das aus akademischem Interesse), und zwar als template, also
template class DreierVektor {…};

Das funktioniert ganz gut, nur muss ich beim Skalarprodukt das erste Argument komplex konjugieren, falls das Template complex ist. Allerding ist ja complex auch wieder ein Template, und hier beginnen meine Probleme:

ich habe versucht, in der Funktion

template 
S DreierVektor::operator\*(DreierVektor other)  

ein dynamic_cast auf complex zu machen, falls tatsächlich ein complexer Typ gegeben ist. Doch ich versage bei der Syntax dafür. Wer kann mir helfen?

Meine bisherigen Versuche sahen etwa so aus:

template \>
S DreierVektor::operator\*(DreierVektor other){  
 complex c = dynamic\_cast \> x();  
 // x() liefert einen Wert vom Typ S zurück  
 ...  
}  

Dabei gibt es dann einen Fehler:
error: `a’ was not declared in this scope
bezogen auf die erste zitierte Zeile. (gcc version 3.3.5 (Debian 1:3.3.5-13).

Vielen Dank im Voraus,
Moritz

Hallo,

bisher dachte ich immer, es sei nicht schwierig die Syntax
einer Programmiersprache zu erlernen, nur die Semantik sei
manchmal kompliziert…

Willkommen in der wunderbaren Welt von C++… Da ist _beides_ schwer.

Meine bisherigen Versuche sahen etwa so aus:

template >
S DreierVektor::operator*(DreierVektor
other){
complex c = dynamic_cast >
x();
// x() liefert einen Wert vom Typ S zurück

}

Dabei gibt es dann einen Fehler:
error: `a’ was not declared in this scope
bezogen auf die erste zitierte Zeile. (gcc version 3.3.5
(Debian 1:3.3.5-13).

Ich habe keine Zeit das jetzt selber auszuprobieren - aber ich denke das Problem ist letztlich das

template >

der Templatesprache etwas zuviel abverlangt. Statt eines einfachen Parameters übergibst du hier etwas, das
sozusagen einen Constraint auf das zweite Argument legt - nämlich das es ein complex sein muss. Das kann C++
nicht.

Was du tun kannst (glaube ich) ist sowas:

template class Complex : public ComplexMarker { … }

Dann kannst du den dynamic cast auf ComplexMarker machen. Hoffe du verstehst was ich meine.

MfG Diez

Hallo,

bisher dachte ich immer, es sei nicht schwierig die Syntax
einer Programmiersprache zu erlernen, nur die Semantik sei
manchmal kompliziert…

Willkommen in der wunderbaren Welt von C++… Da ist _beides_
schwer.

Tja, das musste ich auch bemerken… warum können wir nicht Eiffel lernen… oder Perl…

Ich habe keine Zeit das jetzt selber auszuprobieren - aber ich
denke das Problem ist letztlich das

template >

der Templatesprache etwas zuviel abverlangt. Statt eines
einfachen Parameters übergibst du hier etwas, das
sozusagen einen Constraint auf das zweite Argument legt -
nämlich das es ein complex sein muss. Das kann C++
nicht.

Mist. Saftladen:frowning:

Was du tun kannst (glaube ich) ist sowas:

template class Complex : public ComplexMarker
{ … }

Dann kannst du den dynamic cast auf ComplexMarker machen.
Hoffe du verstehst was ich meine.

Hm, aber von einer beliebigen Klasse, die von complex erbt, kann ich doch gar keinen dynamic_cast auf ComplexMarker machen, weil die Klasse nicht zu ComplexMarker konform ist.
Ich werde noch ein bisschen mit dynamic_cast experimenteieren…

Grüße und vielen Dank,
Moritz

Was du tun kannst (glaube ich) ist sowas:

template class Complex : public ComplexMarker
{ … }

Dann kannst du den dynamic cast auf ComplexMarker machen.
Hoffe du verstehst was ich meine.

Hm, aber von einer beliebigen Klasse, die von complex erbt,
kann ich doch gar keinen dynamic_cast auf ComplexMarker
machen, weil die Klasse nicht zu ComplexMarker konform ist.
Ich werde noch ein bisschen mit dynamic_cast
experimenteieren…

Wieso nicht? Wenn ComplexMarker die virtuelle Methode conjugate enthält die in Complex dann implementiert
wird, dann kannst du das doch aufrufen. Insbesondere wenn sie das Objekt selbst änderd (also nicht die
Konjugierte zurückgibt) - denn sonst müsste die Methode ein ComplexMarker zrückgeben, das du dann dynamisch auf
Complex casten müsstest. Wobei - dass _sollte_ auch gehen.

Diez

Hallo,

Wieso nicht? Wenn ComplexMarker die virtuelle Methode
conjugate enthält die in Complex dann implementiert
wird, dann kannst du das doch aufrufen.

Du hast natürlich recht, ich hab mir die Vererbungshierarchie falsch vorgestellt. Das Problem ist, dass complex eine StandardkLasse ist, die ich nicht ändern will (und auch nicht darf)

Grüße,
Moritz

Hallo,

Wieso nicht? Wenn ComplexMarker die virtuelle Methode
conjugate enthält die in Complex dann implementiert
wird, dann kannst du das doch aufrufen.

Du hast natürlich recht, ich hab mir die Vererbungshierarchie
falsch vorgestellt. Das Problem ist, dass complex eine
StandardkLasse ist, die ich nicht ändern will (und auch nicht
darf)

Ok. Dann vielleicht einfach

template

und so weiter. Dann kannst du doch mittels

complex

das complex-template instanziieren.

Diez

Hallo,

ich habs jetzt so gelöst:

ich habe eine zweite Klasse geschrieben:

template 
class DreierVektor \>{
...
};

und den ganzen Mist nochmal implementiert…

Vielen Dank für deine Mühe.

Grüße,
Moritz

Hallo Moritz,

Jetzt habe ich folgende Problem: ich schreibe eine Klasse
DreierVektor (ja, ich weiss, sowas gibts als fertige
Bibliothek, ich schreibe das aus akademischem Interesse), und
zwar als template, also
template class DreierVektor {…};

Das funktioniert ganz gut, nur muss ich beim Skalarprodukt das
erste Argument komplex konjugieren, falls das Template complex
ist. Allerding ist ja complex auch wieder ein Template, und
hier beginnen meine Probleme:

ich habe versucht, in der Funktion

template
S DreierVektor::operator*(DreierVektor
other)

ein dynamic_cast auf complex zu machen, falls
tatsächlich ein complexer Typ gegeben ist. Doch ich versage
bei der Syntax dafür. Wer kann mir helfen?

Es gibt bei Templates die sogenannte Spezialisierung, damit kannst Du für Sonderfälle anderen Code verwenden (steht u.a. beschrieben im Buch von Stroustrup). Damit hättest Du einmal

 template 
 S operator\*(DreierVektor const& left, DreierVektor const& right);  

und zum zweiten

 template 
 complex operator\*(DreierVektor \> const& left, DreierVektor \> const& right);  

Ich habe das jetzt außerhalb der Klasse geschrieben, da ich weiß, daß es da funktioniert, ob man nur eine Methode spezialisieren kann weiß ich nicht.

Meine bisherigen Versuche sahen etwa so aus:

template >
S DreierVektor::operator*(DreierVektor
other){
complex c = dynamic_cast >
x();
// x() liefert einen Wert vom Typ S zurück

}

Dabei gibt es dann einen Fehler:
error: `a’ was not declared in this scope
bezogen auf die erste zitierte Zeile. (gcc version 3.3.5
(Debian 1:3.3.5-13).

Wenn ‚a‘ kein Klassenobjekt ist, dann ist der Fehler wohl offensichtlich. In so einem Fall hilft eventuel auch die typinformation (Stichwort: typeid), da mußt Du dann schauen, wie das mit Templates funktioniert.

Gruß
Diether