Kann ich eine Template-Spezialisierung aus einer Typliste deklarieren?

7

Ziemlich sicher, ich kenne die Antwort schon, aber es ist einen Versuch wert.

Sagen wir also, ich habe eine Typliste:

%Vor%

Das enthält einige Objekte:

%Vor%

Jetzt habe ich eine Template-Klasse ( baz ), die eines dieser Objekte aufnehmen kann. Aber wegen der Codebasisgröße und der Kompilierungszeiten möchte ich die Implementierung meiner Vorlagenmethode in einer cpp-Datei haben.

Also am Ende von baz.cpp habe ich:

%Vor%

Das Problem ist, dass ich viele Klassen wie baz habe und auch die Liste der Objekte, mit denen sie arbeiten, ändert sich ständig. Also ... kann ich meine einzelne Typliste von Objekten trotzdem behalten und diese in der cpp-Datei jedes baz -ähnlichen Objektes zur Spezialisierung verwenden? Dann muss ich nur meine Typliste aktualisieren, wenn ich ein neues Objekt habe und alle Objektdateien neu erstellt werden.

    
Sam Kellett 07.09.2015, 18:23
quelle

5 Antworten

9

Die template <> class baz<foo>; -Zeile forwards deklariert eine Spezialisierung und keine Template-Instantiierung, von der ich annehme, dass sie das ist, was Sie wollen.

Ich glaube nicht, dass es einen direkten Weg gibt, dies zu tun, Sie müssen etwas Metaprogrammierung machen. Sie können Boost.Preprocessor verwenden, um den gesamten benötigten Code zu generieren:

%Vor%

Es kann einen Weg geben, dies ohne Präprozessor zu tun, aber dies würde zusätzliche Anforderungen an den baz -Typ stellen. Der Punkt besteht darin, den Typ in einem Kontext zu verwenden, in dem er instanziiert werden muss, einschließlich aller seiner Methoden.

    
Andrey Semashev 12.10.2015, 15:02
quelle
3

Ich bin mir ziemlich sicher, dass das ohne den Präprozessor nicht möglich ist. Möglicherweise können Sie das Vorlagenargumentpaket aus einem Argument rekonstruieren, aber Sie müssen eine Instanz des Arguments übergeben, die nicht optimal ist. Zweitens sind explizite Template-Instanziierungen im Blockbereich (d. H. In einer Template-Funktion) nicht erlaubt, so dass es keine Möglichkeit gibt, eine Template zu schreiben, die explizit eine andere Vorlage instanziiert.

Wie Nir angibt, warum verwenden Sie nicht einfach ein X-Makro ?

%Vor%

Aktualisieren Sie jetzt MY_FOREACH_TYPES, wenn sich Ihre Typliste ändert.

    
Matthew 12.10.2015 15:06
quelle
3

Das Wichtigste zuerst: Die korrekte Syntax für die explizite Klassenvorlageninstanziierung lautet

%Vor%

nicht template <> class baz<foo> , das ist eine explizite Klassenvorlagenspezialisierung (Vorwärtsdeklaration).

Eine Möglichkeit könnte darin bestehen, eine Klasse instanziieren, die so aussieht

%Vor%

würde die implizite Instanziierung von baz<foo> , baz<bar> , baz<quux> erzwingen. Nun, aber Sie möchten dies von typelist erstellen. Das typelist ist ein bereits spezialisiertes Template und es gibt in C ++ keine Möglichkeit, über Template-Parameter in typelist von der "Außenwelt von typelist " zu iterieren.

Eine andere Möglichkeit wäre die Verwendung von Makro, aber selbst im Makro können Sie nicht Ihre ursprüngliche typelist verwenden. Ich würde schließen, Ihr Problem hat keine Lösung mit gegebenem typelist .

Als eine Lösung würde ich die Template-Instanziierung auf dem Compiler wenn möglich lassen. Nicht verwendete Vorlagen werden in diesem Fall nicht instanziiert. Die langsame Kompilierung ergibt sich aus der Art und Weise, wie die Meta-Programme spezifiziert werden.

    
Lukáš Bednařík 13.10.2015 15:26
quelle
2

Eine Version, um mit einem normalen Präprozessor zu arbeiten

%Vor%     
AndreyS Scherbakov 13.10.2015 11:21
quelle
1

Das würde den Trick machen. Irgendwann mit einer Spezialisierung der Typliste mit nur einem (oder keinem) Typen.

%Vor%     
prgasp77 14.10.2015 14:34
quelle