28 Stimmen

C++ Template Metaprogramming - Ist es möglich, den generierten Code auszugeben?

Ich möchte einige Codevorlagen debuggen, um sie besser zu verstehen.
Leider bin ich neu in der Template-Metaprogrammierung und es ist schwer für mich, hineinzukommen.

Wenn ich versuche, die vorverarbeiteten Quelldateien auszugeben, erhalte ich 125 000 Codezeilen :/

Gibt es also eine Möglichkeit, den generierten Code zu sehen? (Die Bibliothek, die ich benutze, ist SeqAn )

2 Stimmen

Nein, aber es sollte so sein. Jemand sollte dies als ein Clang-Projekt machen :D

0 Stimmen

Beachten Sie, dass aufgrund von SFINAE der Code, den Sie erhalten würden, wenn Sie einfach jede Vorlage durch eine fest kodierte Alternative ersetzen, wäre wahrscheinlich illegal. Solange sie nicht aufgerufen wird, kann eine Methode einer Template-Klasse z. B. durchaus Dinge aufrufen, die nicht existieren.

1 Stimmen

@JosephGarvin Es gibt jetzt ein Clang-basiertes Projekt (s) für diese. Die letzte aktive Version des Templight, der Clang-basierte Template-Instanziierungs-Profiler und -Debugger , Templer-Visualisierer sowie Metashell .

26voto

jalf Punkte 235501

Nein, im Allgemeinen ist das nicht möglich. Schablonen sind einfach Teil der C++-Sprache, sie sind kein separater Präprozessor, also erzeugen sie keinen C++-Code.

Die übliche Lösung besteht darin, Ihren Code mit statischen Asserts und anderen Tests zu versehen, um zu überprüfen, ob die richtigen Vorlagen auf die richtige Weise instanziiert werden.

Wenn Sie sich einmal in Ihrer Metaprogrammierung verirrt haben, können Sie mit diesem einfachen Trick herausfinden, welcher Typ ein Schablonenparameter wirklich ist:

// given a variable t of an unknown type T
int*** i = t;

Wenn der Compiler auf dieses Problem stößt, gibt er eine einfache Fehlermeldung aus: "Can not convert <long, detailed typename> to int***", so dass Sie leicht überprüfen können, ob der Template-Parameter T tatsächlich der Typ ist, den Sie für richtig erachten.

24voto

Nein, ist es nicht. Der Präprozessor hat nichts mit der Schablonenverarbeitung zu tun, die vom Compiler durchgeführt wird. Schablonen erzeugen keinen C++-Code, genauso wenig wie ein Funktionsaufruf - sie sind ein integraler Bestandteil der Sprache C++ selbst.

0 Stimmen

Dies gilt zwar generell, aber theoretisch auch für den Präprozessor. In der Praxis ist es am einfachsten, C++-ähnlichen Code als Ausgabe des Präprozessors zu erzeugen, aber nicht für Template-Instanziierungen. Der umgekehrte Fall wäre zwar unverhältnismäßig schwierig, aber technisch nicht unmöglich. Das Hauptproblem liegt in der Namenssuche, und der Compiler könnte bei der Instanziierung von Schablonen eindeutige Namen erzeugen.

0 Stimmen

Um ehrlich zu sein, können Sie immer noch den Debugger verwenden, um den berechneten Typ anzuzeigen, wenn Sie ihn instanziieren. Ich habe ein Beispiel für die Verwendung von Visual C++ erstellt. Ich habe es für meine Metaprogramme sehr oft verwendet.

16voto

jmihalicza Punkte 1998

Siehe meine Veröffentlichung über die Fehlersuche in C++-Vorlagen-Metaprogrammen

Auf Seite 6 können Sie sehen, wie es funktioniert. Für bestimmte Zwecke benötigen Sie nicht die gesamte Toolchain, sondern können sie von Hand erstellen.

Ich habe ein Add-in für Visual C++ entwickelt, mit dem man Haltepunkte usw. setzen kann, aber das war eher ein Proof of Concept als ein Werkzeug für den täglichen Gebrauch.

Wir haben an einem grafischen Frontend gearbeitet, das alle Instanzen anzeigt, Debugging und Profiling ermöglicht. Leider können wir kein Veröffentlichungsdatum für dieses Tool versprechen, da wir es in unserer recht begrenzten Freizeit entwickeln.

UPDATE: Der Debugger und Profiler ist verfügbar ici

UPDATE: C++Now-Präsentation

6voto

Daniel Earwicker Punkte 111630

Dies ist möglicherweise die Antwort auf Ihre Frage:

C++ Template-Präprozessor-Werkzeug

Die letzte Person, die danach gefragt hat, scheint zufrieden gewesen zu sein - obwohl ich mir nicht vorstellen kann, warum! Die Ausgabe eines C++-Compilers in C ist in der Regel ziemlich unlesbar, da sie nicht als Verständnishilfe gedacht ist, sondern lediglich als eine Art portabler Assembler.

1voto

ovanes Punkte 5364

Im Allgemeinen ist es nicht möglich, den gesamten Code auszugeben. Aber was ich sehr interessant fand, ist die Möglichkeit, den Visual C++ Debugger zu verwenden, um den Typ anzuzeigen. Nehmen Sie dieses einfache Meta-Programm:

template<class Head, class Tail>
struct type_list
{
  typedef Head head;
  typedef Tail tail;
};

struct null_type
{};

template<class List>
struct list_head
{
  typedef typename List::head head;
};

template<class List>
struct list_tail
{
  typedef typename List::tail tail;
};

template<class List>
struct list_length
{
  static const size_t length = 1+list_length< typename list_tail<List>::tail >::length;
};

template<>
struct list_length<null_type>
{
  static const size_t length = 0;
};

int main()
{
  typedef 
    type_list
    < int
    , type_list
      < double
      , type_list
        < char
        , null_type
        >
      >
    >       my_types;

  my_types test1;

  size_t length=list_length<my_types>::length;

  list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2;

}

Ich habe gerade meine Meta-Typen instanziiert. Diese sind immer noch leere C++-Klasseninstanzen, die mindestens 1 Byte lang sind. Jetzt kann ich einen Haltepunkt nach der letzten Instanzierung von test2 setzen und sehen, welche Typen/Werte Länge, test1 und test2 haben:

Das zeigt der Debugger:

length  3   unsigned int
test1   {...}   type_list<int,type_list<double,type_list<char,null_type> > >
test2   -52 'Ì' char

Jetzt wissen Sie, dass der Kopf Ihnen ein Zeichen zurückgegeben hat, Ihre Liste enthält int, double, char und wird durch null_type abgeschlossen.

Das hat mir sehr geholfen. Manchmal muss man die wirklich chaotische Schrift in einen Texteditor kopieren und in eine lesbare Form bringen, aber das gibt einem die Möglichkeit nachzuvollziehen, was drin ist und wie es berechnet wird.

Ich hoffe, das hilft,
Ovanes

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X