Partial Specialization
-
Hallo,
leider nochmals eine Frage zu Templates. Leider konnte ich beim googlen hierauf keine Antwort. Zumindest keine die mir wirklich weiter hilft.
Könnt ihr mir sagen, was ich falsch mache?
template<int geschwindigkeit, bool vierraeder> struct fahrzeug; template<> struct fahrzeug< geschwindigkeit<200 , true> { string Autoname; }; template<> struct <fahrzeug< geschwindigkeit > 300, false> { string schnelles_motorrad; };Viele Grüße
MM
-
Du verstösst gegen die Syntax. Deine < und > sind völlig an falschen Orten platziert und du gibst auch unnötige, bzw. fehlerhafte Bezeichner an. Es müsste wohl so lauten:
template<int geschwindigkeit, bool vierraeder> struct fahrzeug; template<> struct fahrzeug<200 , true> { string Autoname; }; template<> struct fahrzeug<300, false> { string schnelles_motorrad; };Wobei ich mich allerdings über dieses Beispiel schon ein wenig wundere. Für sowas würde ich keine Templatespezialisierung verwenden

Grüssli
-
Hallo Dravere,
leider bildet diese nicht das ab, was ich haben möchte. Bei mir war das '<' ein kleiner Operator.
Was mache ich nun am besten? Ein Makro "kleiner" und dafür dann beide Templateparameter bool?
Viele Grüße
MM
-
MrMilk schrieb:
leider bildet diese nicht das ab, was ich haben möchte.
Dann sag, was du haben möchtest! Denn dein Beispiel ist einfach syntaxmässig falsch. Dazu braucht man nicht einmal einen Kompiler.
Grüssli
-
Ich denke, dass MrMilk jeweils eine Spezialisierung von fahrzeug<geschw,vierr> für den Fall (geschw<200 && vierr) und für den Fall (geschw>300 && !vierr) erzeugen möchte.
Das geht allerdings niht so einfach. Zumindest gibt es keine "partielle Spezialisierung" für nicht-Typ-Parameter.
MrMilk kann aber so etwas machen:
template<int Klasse, bool Vierrad> struct fahr_dings_impl { /*...*/ }; template<> struct fahr_dings_impl<0,true> { /*...*/ }; // Fall "<200" template<> struct fahr_dings_impl<2,false> { /*...*/ }; // Fall ">300" template<int Geschw, bool Vierrad> struct fahrzeug : fahr_dings_impl<((Geschw>=200)+(Geschw>300)),Vierrad> {}; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // berechnet aus der Geschwindigkeit die "Klasse"Das übergeordete Ziel von MrMilk lässt sich aber bestimmt auch eleganter lösen. Nur dazu fehlen die Informationen.
Gruß,
SP
-
Hallo Dravere,
ich möchte, dass bei einem Wert der Variable 'geschwindigkeit' mit kleiner als 200 und wenn die Variable 'vierraeder' wahr ist, die erste Struktur genommen wird.
Sollte der Werte der Variable 'geschwindigkeit' größer als 300 und die Variable 'vierraeder' falsch sein, dann die zweite Struktur.
Tut mir leid, dass ich mich so schlecht ausdrücke.
Verstehst du worauf ich hinaus möchte?Viele Grüße
MM
-
MrMilk schrieb:
Hallo,
leider nochmals eine Frage zu Templates. Leider konnte ich beim googlen hierauf keine Antwort. Zumindest keine die mir wirklich weiter hilft.
Könnt ihr mir sagen, was ich falsch mache?
template<int geschwindigkeit, bool vierraeder> struct fahrzeug; template<> struct fahrzeug< geschwindigkeit<200 , true> { string Autoname; }; template<> struct <fahrzeug< geschwindigkeit > 300, false> { string schnelles_motorrad; };Viele Grüße
MMDu musst das spezialisieren was du deklariert hast. Und dein allgemeines Template hat als ersten Parameter ein int, die Spezialisierungen aber ein bool.
Wenn du allgemein nach schnell oder langsam unterscheiden willst, aber dennoch die Geschwindigkeiten mit eine Rolle spielen, kannst du sowas machen:
template<bool schnell, int geschw, bool vierraeder> struct fahrzeug_schnellangsam { void brumm() { std::cout << "ich bin schnell (" << geschw << ")!" << std::endl; } //code fuer schnelles auto }; template<int geschw, bool vierraeder> struct fahrzeug_schnellangsam<false /*nicht schnell*/, geschw, vierraeder> { void brumm() { std::cout << "tucker, tucker... ("<< geschw << ")" << std::endl ; } //code fuer langsames fahrzeug }; template<int geschw, bool vierraeder> struct fahrzeug //das was du am Ende benutzt : public fahrzeug_schnellangsam<(geschw>200)/*klammern sind pflicht!*/, geschw, vierraeder> {}; int main() { fahrzeug<290, true> flitzer; fahrzeug<90, true> trecker; flitzer.brumm(); trecker.brumm(); }
-
MrMilk schrieb:
Tut mir leid, dass ich mich so schlecht ausdrücke.
Verstehst du worauf ich hinaus möchte?Aha, jetzt! Hättest du das doch von Anfang an hingeschrieben

Aber inzwischen haben zwei geantwortet, mit zwei von vielen Möglichkeiten.Wichtig ist, dass man keine Bedingungen für einen Parameter setzen kann. Wenn du spezialisiert, kannst du einfach nur einen oder mehrere Parameter durch einen festen Wert oder Typ ersetzen.
Wenn du Bedingungen einführen willst, dann musst du entsprechende Hilfstrukturen dazunehmen, wie es Sebastian Pizer und pumuckl gezeigt haben.Womit lernst du aktuell die Templatemetaprogrammierung?
Grüssli
-
Hallo,
ich möchte mit "Modern C++ Design" anfangen. Dieses hat bei Amazon sehr gute Bewertungen bekommen. Bevor ich damit anfange, wollte ich mir grundsätzlich noch einmal Templates anschauen.
Eine Frage hab ich noch zu der Lösung von pumuckel:
template<int geschw, bool vierraeder> struct fahrzeug_schnellangsam<false /*nicht schnell*/, geschw, vierraeder> { void brumm() { std::cout << "tucker, tucker... ("<< geschw << ")" << std::endl ; } //code fuer langsames fahrzeug };Fehlt hier eventuell ein Parameter (bool schnell)?
bzw. wieso sind hier keine Spitzen klammern hinter dem Namen der Struktur
template<bool schnell, int geschw, bool vierraeder> struct fahrzeug_schnellangsam { void brumm() { std::cout << "ich bin schnell (" << geschw << ")!" << std::endl; } //code fuer schnelles auto };Um mich zu testen, ob ich dieses richtig verstanden hab:
Idee dieser Lösungsart ist dass noch eine spezialisierte Struktur im Hintergrund auf die passend abgebildet wird. Angenommen, ich möchte jetzt in drei Bereich aufteilen: bis 100, bis 1000 und ende offen, dann würde man zwei bool Variablen nehmen, oder?
Viele grüße
MM
-
MrMilk schrieb:
template<int geschw, bool vierraeder> struct fahrzeug_schnellangsam<false /*nicht schnell*/, geschw, vierraeder> { void brumm() { std::cout << "tucker, tucker... ("<< geschw << ")" << std::endl ; } //code fuer langsames fahrzeug };Fehlt hier eventuell ein Parameter (bool schnell)?
Nein. Dies ist eine partielle spezialisierung von template<bool, int, bool> struct fahrzeug_schnellangsam, wo das erste bool fest mit false belegt ist.
bzw. wieso sind hier keine Spitzen klammern hinter dem Namen der Struktur
template<bool schnell, int geschw, bool vierraeder> struct fahrzeug_schnellangsam { void brumm() { std::cout << "ich bin schnell (" << geschw << ")!" << std::endl; } //code fuer schnelles auto };Dies ist der allgemeine Fall, also keine Spezialisierung. Man könnte das in etwa so lesen: "ALLE fahrzeuge sagen 'ich bin schnell' (allgemeiner Fall), ABER die fahrzeuge wo der erste parameter false ist, sagen 'ich bin langsam' (spezialisierung)"
Man hätte auch das allgemeine Template nur deklarieren können, um es dann einmal für true und eimal für false zu spezialisieren.
Angenommen, ich möchte jetzt in drei Bereich aufteilen: bis 100, bis 1000 und ende offen, dann würde man zwei bool Variablen nehmen, oder?
Sinnvoller wäre da vermutlich ein enum, dessen Wert dann entweder über den ?:-Operator entschieden wird oder über ein weiteres helfertemplate:
enum TempoSelect { LAHM, NORMAL, SCHNELL }; template<TempoSelect schnell, int geschw, bool vierraeder> struct fahrzeug_schnellnormallangsam { void brumm() { std::cout << "ich bin schnell (" << geschw << ")!" << std::endl; } //code fuer schnelles auto }; template<int geschw, bool vierraeder> struct fahrzeug_schnellnormallangsam<NORMAL, geschw, vierraeder> { void brumm() { std::cout << "voll normal... ("<< geschw << ")" << std::endl ; } //code fuer langsames fahrzeug }; template<int geschw, bool vierraeder> struct fahrzeug_schnellnormallangsam<LAHM, geschw, vierraeder> { void brumm() { std::cout << "tucker, tucker... ("<< geschw << ")" << std::endl ; } //code fuer langsames fahrzeug }; template<int geschw, bool vierraeder> struct fahrzeug //das was du am Ende benutzt : public fahrzeug_schnellnormallangsam<((geschw>200)?SCHNELL:(geschw<100)?LAHM:NORMAL)/*klammern sind pflicht!*/, geschw, vierraeder> {}; int main() { fahrzeug<290, true> flitzer; fahrzeug<130, true> meinauto; fahrzeug<90, true> trecker; meinauto.brumm(); flitzer.brumm(); trecker.brumm(); }Auch hier hätte man wieder den allgemeinen Fall nur deklarieren können und für SCHNELL eine partielle spezialisierung machen.
ich möchte mit "Modern C++ Design" anfangen. Dieses hat bei Amazon sehr gute Bewertungen bekommen. Bevor ich damit anfange, wollte ich mir grundsätzlich noch einmal Templates anschauen.
Ich empfehle vorher "C++ Templates - The Complete Guide" zu lesen. Die vermitteln sehr gut die Grundlagen, so dass man hinterher Alexandrescus nette Spielereien recht einfach verstehen kann.
-
Super, nun habe ich es verstanden. Danke für euere Geduld.
Ich habe es so gelöst, dass ich als erstes den Standardfall geschrieben habe und von diesem dann die Spezialfälle abgeleitet hab.
Das Template besteht aus einem Integer und zwei boolschen Parametern. Die vier bool-Fälle wurden abgedeck. Somit sollte ich immer in einem Spezialfall laden.
Viele Grüße
MM