Verwandte Fragen: eins, zwei
Nachdem ich mehrere Tage lang versucht habe, CRTP zu verstehen, verstehe ich jetzt anscheinend noch weniger als zuvor 🙂
Betrachten Sie den folgenden Code:
01 #include <iostream>
02
03 template <class IMPL>
04 class Interace
05 {
06 public:
07 typedef typename IMPL::TYPE TYPE; // ERROR: "...invalid use of incomplete type..."
08 void foo() { IMPL::impl(); } // then why does this work?
09 };
10
11 class Implementation : public Interface<Implementation>
12 {
13 public:
14 typedef int TYPE;
15 static void impl() { std::cout << "impl() " << std::endl; }
16 };
17
18
19 int main()
20 {
21 Implementation obj;
22 obj.foo();
23 }
Die Fragen sind:
-
Warum kann ich Funktion aus aufrufen
IMPL::
(Zeile 8), kann aber nicht auf Typdateien zugreifen (Zeile 7)? In der verwandten Frage heißt esIMPL
ist an dieser Stelle ein unvollständiger Typ. Aber warum ist dann Zeile 8 richtig? -
Was ist die Reihenfolge der Typdeklaration/Definition? Wie ich es sehe:
a.
Interface
Vorlage – OK. Bringt bis zur Instanziierung keine Problemeb. Zeile 11 — danach
class Implementation
—Implementation
Typ deklariert, aber nicht definiert.c. Zeile 11 — danach
Interface<Implementation>
— Template-Instanziierung. An diesem PunktImplementation
ist aufgrund von Schritt (b) bereits bekannt (aber nicht definiert!). Compiler “injiziert” Code mitIMPL
Ersetzt mitImplementation
. Hier sind aus meiner Sicht weder Zeile 7 noch Zeile 8 nicht legal, da der Compiler das zu diesem Zeitpunkt noch nicht weißImplementation
hat diese Mitglieder. Woher weiß es als?
Oder geht Instanziierung vielleicht wirklich in Zeile 21? Aber warum funktioniert in diesem Fall die Zeile 07 nicht?
Ich denke mehr darüber nach, weniger Verständnis für die Grundlagen von C++, die ich habe. Jede Klarstellung wird geschätzt.