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.
Das würde den Trick machen. Irgendwann mit einer Spezialisierung der Typliste mit nur einem (oder keinem) Typen.
%Vor%Eine Version, um mit einem normalen Präprozessor zu arbeiten
%Vor%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 ( %code% ), 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 %code% 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 %code% -ähnlichen Objektes zur Spezialisierung verwenden? Dann muss ich nur meine Typliste aktualisieren, wenn ich ein neues Objekt habe und alle Objektdateien neu erstellt werden.
Das Wichtigste zuerst: Die korrekte Syntax für die explizite Klassenvorlageninstanziierung lautet
%Vor%nicht %code% , 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 %code% , %code% , %code% erzwingen. Nun, aber Sie möchten dies von %code% erstellen. Das %code% ist ein bereits spezialisiertes Template und es gibt in C ++ keine Möglichkeit, über Template-Parameter in %code% von der "Außenwelt von %code% " zu iterieren.
Eine andere Möglichkeit wäre die Verwendung von Makro, aber selbst im Makro können Sie nicht Ihre ursprüngliche %code% verwenden. Ich würde schließen, Ihr Problem hat keine Lösung mit gegebenem %code% .
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.
Die %code% -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 %code% -Typ stellen. Der Punkt besteht darin, den Typ in einem Kontext zu verwenden, in dem er instanziiert werden muss, einschließlich aller seiner Methoden.