Template-Parameter kapseln

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Template-Parameter kapseln

Beitrag von eXile »

Und mal wieder etwas aus meinen Template-Abenteuern. Ich habe die kurze Frage, ob es irgendeine allgemein anwendbare Möglichkeit gibt, die Template-Parameterliste zu kapseln. Was ich damit meine, zeige ich an einem trivialen Beispiel:

Code: Alles auswählen

template <int i1, int i2>
struct adder
{
	enum
	{
		result = i1 + i2
	};
};

template <adder a, int i3>
struct fusedmultiplyadder1 // Geht natürlich nicht.
{
	enum
	{
		result = a::result * i3;
	};
};

template <int i1, int i2, int i3>
struct fusedmultiplyadder2 // Geht; Template-Liste wächst gegen infinity, and beyond!
{
	enum
	{
		result = adder<i1, i2>::result * i3
	};
};
Wie man sieht, geht bei fusedmultiplyadder2 die Parameterliste gegen unendlich, wenn man mal etwas Komplexeres machen will. Gibt es irgendeine gültige Variante von fusedmultiplyadder1?
Benutzeravatar
dot
Establishment
Beiträge: 1746
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Template-Parameter kapseln

Beitrag von dot »

Naja, ich vermute mal, du willst einfach variadic templates haben!?
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Template-Parameter kapseln

Beitrag von CodingCat »

Du musst adder a nur durch typename a ersetzen. ;) Ja, das ist dann natürlich etwas überflexibel, für mehr bräuchtest du Concepts.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1746
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Template-Parameter kapseln

Beitrag von dot »

Jop, concepts + variadic templates...Ich fürchte im Moment müsste man da ansonsten wohl mit dem Präprozessor ran...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Template-Parameter kapseln

Beitrag von CodingCat »

Naja, ich sehe an der flexiblen Lösung nichts schlechtes, und einfach ist sie obendrein. Die Frage ist, warum es überhaupt der Einschränkung auf adder bedarf, vermutlich hängt noch irgendetwas komplexeres hinter diesem reduzierten Beispiel.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1746
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Template-Parameter kapseln

Beitrag von dot »

Ja, das stimmt natürlich...
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Template-Parameter kapseln

Beitrag von eXile »

CodingCat hat geschrieben:Naja, ich sehe an der flexiblen Lösung nichts schlechtes, und einfach ist sie obendrein.
Ja, es ist dann halt duck typing.
CodingCat hat geschrieben:Die Frage ist, warum es überhaupt der Einschränkung auf adder bedarf, vermutlich hängt noch irgendetwas komplexeres hinter diesem reduzierten Beispiel.
Ja, das Beispiel ist zu stark reduziert; es soll hier im Anwendungsfall nur eine bestimmte Klasse an der Stelle verwendet werden dürfen. Wie gesagt: Das sind nur Hilfsklassen, um Schreibarbeit durch Verkürzung der Template-Parameter-Liste zu sparen, und diese Hilfsklassen können von außen gar nicht benutzt werden. Variadic Templates brauche ich hier auch nicht, da war das gegebene Beispiel einfach zu weit von meinem Anwendungsfall entfernt; sorry für das schlechte Beispiel.

Jetzt auch noch hier jeder Template-Klasse GUIDs zu geben, nur um Concepts mit SFINAE zu emulieren, geht mal gar nicht; aber so etwas habt ihr ja auch nicht vorgeschlagen. ;)

Ich habe es jetzt mal mit typename durchimplementiert, und gerade die angesprochene Flexibilität hat mir in den Hintern gebissen, weil ich doch auf ein paar Template-Parameter der verkapselnden Hilfsklassen zugreifen musste. Also wieder Kommando zurück, zurück zu den riesigen Listen, aber trotzdem danke für die Hilfe.

And now: To infinity, and beyond …
… und ich habe vorhin mit der Warnung C4503 die Name-Decorating-Schallmauer durchbrochen.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Template-Parameter kapseln

Beitrag von CodingCat »

eXile hat geschrieben:Ich habe es jetzt mal mit typename durchimplementiert, und gerade die angesprochene Flexibilität hat mir in den Hintern gebissen, weil ich doch auf ein paar Template-Parameter der verkapselnden Hilfsklassen zugreifen musste. Also wieder Kommando zurück, zurück zu den riesigen Listen, aber trotzdem danke für die Hilfe.
Hm, ich verstehe nicht, inwiefern du mit der Einschränkung besser auf Template-Parameter zugreifen könntest? Mir fallen eigentlich nur 2 Varianten ein:
  • Pattern Matching
    eXile hat geschrieben:
    CodingCat hat geschrieben:Naja, ich sehe an der flexiblen Lösung nichts schlechtes, und einfach ist sie obendrein.
    Ja, es ist dann halt duck typing.
    Fast, aber nicht im Rahmen von Pattern Matching. Hier könntest du sogar ganz einfach eine rekursive Dekomposition mit sehr spezifischen Einschränkungen durchführen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Template-Parameter kapseln

Beitrag von eXile »

CodingCat hat geschrieben:Hm, ich verstehe nicht, inwiefern du mit der Einschränkung besser auf Template-Parameter zugreifen könntest? Mir fallen eigentlich nur 2 Varianten ein:
  1. Redefinition
  2. Pattern Matching
    Ja, das sind die Lösungen, die sich hier auch herauskristallisieren, und die Beschränkungen von C++ zeigen. Hätte ich eine Variante, welche:
    1. die Template-Template-Parameter eines Template-Parameters nimmt, und
    2. diese direkt der Template-Parameterliste als Template-Parameter hinzufügt,
    [/list][/list]
    würden sich ein paar Probleme hier verflüchtigen. Oder kurz: Template-Template-Parameter sollen so wie normale Template-Parameter behandelt werden; was aktuell offensichtlich unmöglich ist.
    CodingCat hat geschrieben:Fast, aber nicht im Rahmen von Pattern Matching. Hier könntest du sogar ganz einfach eine rekursive Dekomposition mit sehr spezifischen Einschränkungen durchführen.
    Das ist korrekt! Wobei bei mir auch noch hinzukommt, dass viele der dekomponierenden Einschränkungsklassen auch noch unterschiedlicher Natur sein können; siehe dafür diese Erweiterung deines Beispiels.

    Gibt es eine einfache Möglichkeit, das gültig zu machen? (Warum es nicht geht, ist mir klar: Es sind einfach unterschiedliche Typen. Ich brauche also „laxeres“ Pattern Matching.)
    Benutzeravatar
    CodingCat
    Establishment
    Beiträge: 1857
    Registriert: 02.03.2009, 21:25
    Wohnort: Student @ KIT
    Kontaktdaten:

    Re: Template-Parameter kapseln

    Beitrag von CodingCat »

    eXile hat geschrieben:Hätte ich eine Variante, welche:
    1. die Template-Template-Parameter eines Template-Parameters nimmt, und
    2. diese direkt der Template-Parameterliste als Template-Parameter hinzufügt,
    würden sich ein paar Probleme hier verflüchtigen. Oder kurz: Template-Template-Parameter sollen so wie normale Template-Parameter behandelt werden; was aktuell offensichtlich unmöglich ist.
    Das musst du genauer erklären. Inwiefern sollen Template-Template-Parameter wie Template-Parameter behandelt werden?
    eXile hat geschrieben:Wobei bei mir auch noch hinzukommt, dass viele der dekomponierenden Einschränkungsklassen auch noch unterschiedlicher Natur sein können; siehe dafür diese Erweiterung deines Beispiels. Gibt es eine einfache Möglichkeit, das gültig zu machen? (Warum es nicht geht, ist mir klar: Es sind einfach unterschiedliche Typen. Ich brauche also „laxeres“ Pattern Matching.)
    Ja, einfach implizite Konvertierungen nutzen: http://ideone.com/K0k2b
    Mich würde ja echt interessieren, was du damit eigentlich baust. ;)
    alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
    Benutzeravatar
    CodingCat
    Establishment
    Beiträge: 1857
    Registriert: 02.03.2009, 21:25
    Wohnort: Student @ KIT
    Kontaktdaten:

    Re: Template-Parameter kapseln

    Beitrag von CodingCat »

    Ich konnte es natürlich nicht lassen, noch etwas hübsches zu basteln.
    alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
    Benutzeravatar
    CodingCat
    Establishment
    Beiträge: 1857
    Registriert: 02.03.2009, 21:25
    Wohnort: Student @ KIT
    Kontaktdaten:

    Re: Template-Parameter kapseln

    Beitrag von CodingCat »

    Für den allgemeinen Fall musste ich leider die Automatisierung etwas zurückfahren und noch mit virtual Inheritance nachbessern: http://ideone.com/q1FBz
    alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
    Benutzeravatar
    eXile
    Establishment
    Beiträge: 1136
    Registriert: 28.02.2009, 13:27

    Re: Template-Parameter kapseln

    Beitrag von eXile »

    Das sieht hervorragend aus!

    Für alle, die auch da neben mir noch durchsteigen wollen, habe ich mal die Ableitungskette / -baum / -graphen aufgeschrieben. Für fma1:

    Code: Alles auswählen

    fusedmultiplyadder<adder1<2, 3>, 4>
     : public inherit_base_pattern<adder1<2, 3>, fusedmultiplyadder<adder<2, 3>, 4>>
        : public virtual fusedmultiplyadder<adder<2, 3>, 4>
    Damit matcht fusedmultiplyadder<adder1<2, 3>, 4> auf fusedmultiplyadder<adder<2, 3>, 4>. Und für fma4:

    Code: Alles auswählen

    fusedmultiplyadder1<adder2<2, 3>, 4>
     : public virtual fusedmultiplyadder<adder2<2, 3>, 4>
        : public inherit_base_pattern<adder2<2, 3>, fusedmultiplyadder<adder<2, 3>, 4>>
           : public virtual fusedmultiplyadder<adder<2, 3>, 4>,
       public inherit_base_pattern<adder2<2, 3>, fusedmultiplyadder1<adder<2, 3>, 4>>
        : public virtual fusedmultiplyadder1<adder<2, 3>, 4>
    Damit matcht fusedmultiplyadder1<adder2<2, 3>, 4> auf fusedmultiplyadder1<adder<2, 3>, 4> und auf fusedmultiplyadder<adder<2, 3>, 4>.
    CodingCat hat geschrieben:Mich würde ja echt interessieren, was du damit eigentlich baust. ;)
    Es hat nichts mit Mathematik zu tun, sondern es sind ein paar Hilfsklassen, die enum traits implementieren; als dass man über enums dann iterieren kann, und der Iterator verschiedene Policies besitzt, mit denen man entweder das enum von Anfang bis Ende einmal durchläuft; oder der Iterator am Ende umwrappt, und man den enum immer wieder in einer Schleife durchläuft. Hintergrund ist, dass ich keine Lust mehr hatte, immer auf so etwas wie if(myEnum == lastEnumElement) myEnum = firstEnumElement; else myEnum++; zu testen; nun muss ich nur myEnumIterator++; aufrufen. Wenn ich das auf obiges inherit_base_pattern umgestellt habe, dabei nicht auf die Nase geflogen bin, und das alles auch im g++ kompiliert (oh Gott mache ich dumme Fehler; aber Visual Studio sagt halt nichts) werfe ich das in die Public Domain, natürlich hier veröffentlicht. Und dann sagt ihr mir, warum das alles Scheiße war. :)
    Benutzeravatar
    CodingCat
    Establishment
    Beiträge: 1857
    Registriert: 02.03.2009, 21:25
    Wohnort: Student @ KIT
    Kontaktdaten:

    Re: Template-Parameter kapseln

    Beitrag von CodingCat »

    eXile hat geschrieben:Hintergrund ist, dass ich keine Lust mehr hatte, immer auf so etwas wie if(myEnum == lastEnumElement) myEnum = firstEnumElement; else myEnum++; zu testen; nun muss ich nur myEnumIterator++; aufrufen. Wenn ich das auf obiges inherit_base_pattern umgestellt habe, dabei nicht auf die Nase geflogen bin, und das alles auch im g++ kompiliert (oh Gott mache ich dumme Fehler; aber Visual Studio sagt halt nichts) werfe ich das in die Public Domain, natürlich hier veröffentlicht. Und dann sagt ihr mir, warum das alles Scheiße war. :)
    Auweia, dann hoffe ich mal, dass dir virtual- und Mehrfachvererbung nicht sämtliche Optimierung ausschaltet. ;)
    alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
    Antworten