Der folgende Code kompiliert nicht in g ++ 7.2.0
%Vor%Mit Fehler
%Vor%Ich verstehe nicht, was damit nicht stimmt (abgesehen davon, dass ich ein dummes Beispiel bin). Clang 4.0.1 scheint es zu akzeptieren und ich bin mir ziemlich sicher, dass es unter g ++ 5.4 kompiliert wurde Außerdem: Wenn ich alle Vorlagen lösche, kompiliert das ok.
Ist dieser Fehler im Compiler oder verstoße ich gegen eine Regel, die ich nicht kenne?
BEARBEITEN Es scheint, dass es nicht mehr funktioniert, beginnend mit gcc 7.x Ссылка
Ich weiß nicht, ob GCC rechtmäßig an dieser Konstruktion balkert, aber es scheint so, als ob das totale Fehlen von Request<Internal>
im Typ von setContent
ist verwirrend es. Der einzige Grund, warum Sie auf Request<Internal>
verweisen können, ist der Name der injizierten Klasse, der aus dem Gültigkeitsbereich der Definition stammt.
Ich glaube nicht, dass Sie hier eine Vorlage wünschen, denn wenn Sie sie mit einem zweiten Typ instanziieren, verletzen Sie die eine Definitionsregel.
%Vor% Wenn es andere Mitglieder Ihrer Klasse gibt, die Internal
verwenden, können Sie sie mit einer Template-Unterklasse
Die andere Alternative ist, dass Sie Internal
in den Argumenten von setContent
oder
%Vor% Beachten Sie, dass Sie weiterhin void setContent(int, Request<Internal> *)
an einen void (*)(int, void *)
Funktionszeiger usw. binden können
Dieser sieht echt knifflig aus. Schauen wir uns die Zeile noch einmal an:
Request<Internal> *ptr = (Request<int>*)voidptr;
Das sind zwei verschiedene Typen. Wie konvertiert man zwischen einem Typ und einem anderen? Nun, der offensichtliche Weg wäre eine Umwandlung von abgeleitet zu basisch.
Nun können Sie sagen, dass Request<int>
keine abgeleitete Klasse ist. Wenn wir uns das ganze Programm anschauen, stimmt das. In der ersten Phase der Template-Kompilierung hat der Compiler noch keine Template-Spezialisierungen gesehen . Es kann immer noch eine Spezialisierung von Request<int>
geben, die später eine Basisklasse (!) Einführen könnte
Ich müsste die geeigneten C ++ - Standards ergreifen, um zu überprüfen, ob sich etwas subtil in diesem Bereich geändert hat, aber von einem technischen Standpunkt aus ist es keine Überraschung, wenn sich ein solcher Code angesichts geringfügiger Compiler-Änderungen als fragil erweist.