Ich bin verwirrt darüber, warum mein Code nicht den Fehler produziert, während alle lesen, die ich über diesen Fehler getan habe, schlägt vor, es sollte.
Die Frage nach diesem Fehler resultierte zeigt sich mit einer ähnlichen Struktur in dem Teil meines Codes (wie erwartet), aber ich kann es nicht in einem kleinen Beispiel reproduzieren (bitte Haftungsausschluss am Ende der sehen Frage).Ungültige Verwendung von unvollständigem Typ - warum kein Fehler in diesem Fall?
Zusammenfassung von dem, was ich zu tun versucht:
- Ich habe eine Struktur (
Tree
), und ich möchte verschiedene Objekte von BasistypFirst
ihm zuweisen. - Konkrete Implementierungen von
First
haben unterschiedliche Rückgabewerte, so werden zwei Dereferenzierungsebenen verwendet: First
ist eine abstrakte Basisklasse, undFirst *
werden verwendet, um verschiedene konkrete Fälle zu behandeln.template <typename Type> class TypedFirst : public First
ist ein abstrakter Typ, der die Funktion mit dem RückgabetypType
definiert.- Schließlich
ConcreteFirstX
sind konkrete Spezialisierungen vonTypedFirst<Type>
.
In tree.tpp
, warum der Anruf an new TF(this)
nicht produzieren die invalid use of incomplete type
Fehler entdeckt? (Die Stelle im Code markiert) Ich denke, der Fehler sollte es sein, weil, während TF
eine Vorlage, wenn ich ConcreteFirstA
verwenden, die tree.tpp
nicht bekannt ist (es ist nicht concretefirsta.h
nicht enthalten oder sogar first.h
, es nur vorwärts erklärt First
)
Der vollständige, kompilierbare und ausführbare Code für dieses Beispiel kann here on pastebin gefunden werden. Hier werde ich aus Gründen der Kürze #define
Wachen und ähnliche Dinge ausschließen. Der Code ist wie folgt:
// tree.h
class First;
class Tree{
public:
Tree() {}
~Tree() {}
template<class TF> // where TF is a ConcreteFirst
void addFirstToTree();
private:
std::map<std::string, First *> firstCollection; // <- "First"'s here
};
#include "tree.tpp"
// tree.tpp
#include "tree.h"
template <class TF> // where TF is a ConcreteFirst
void Tree::addFirstToTree(){
this->firstCollection[TF::name] = new TF(this); // <--- Why does this work?
// ^^^^^^^^^^^^^
}
// first.h
class Tree;
class First{
public:
static const std::string name;
First(const Tree *baseTree) : myTree(baseTree) {}
virtual ~First();
protected:
const Tree *myTree;
};
template <typename Type> class TypedFirst : public First{
public:
static const std::string name;
TypedFirst(const Tree *baseTree) : First(baseTree) {}
Type &value() {return this->_value;}
private:
Type _value;
};
#include "first.tpp"
// first.tpp
#include "first.h"
template <typename Type>
const std::string TypedFirst<Type>::name = "default typed";
// first.cpp
#include "first.h"
First::~First() {}
const std::string First::name = "default";
// concretefirsta.h
#include "first.h"
class ConcreteFirstA : public TypedFirst<int>{
public:
static const std::string name;
ConcreteFirstA(const Tree *baseTree) : TypedFirst<int>(baseTree) {}
~ConcreteFirstA() {}
};
// concretefirsta.cpp
#include "concretefirsta.h"
const std::string ConcreteFirstA::name = "firstA";
Schließlich ist der Code, dass alle zusammen bringt und macht die (in) entsprechende Funktion aufruft:
// main.cpp
#include "tree.h"
#include "first.h"
#include "concretefirsta.h"
int main(){
Tree *myTree = new Tree();
myTree->addFirstToTree<ConcreteFirstA>(); // <-- here! why is this working?
delete myTree;
return 0;
}
DISCLAIMER Diese Frage wurde tatsächlich von einem größeren Problem ausgelöst, das ich im Stack Overflow-Format für zu groß und unzuverlässig hielt. Obwohl ich ursprünglich versucht habe, danach zu fragen, wurde die Frage als zu weit geschlossen und ich versuche nun, sie zu retten, indem ich nur einen Teil der Frage stelle.
Mein Problem ist, dass Ich bekomme den Fehler in einem Stück Code mit identischer Struktur zu diesem: aber ich kann es nicht in einem kleinen Beispiel reproduzieren.
So frage ich warum der Code das folgende Stück nicht Herstellung die Fehlerinvalid use of incomplete type
(wie ich erwarten würde), und ich hoffe, dass wird mir helfen, mein eigentliches Problem zu verstehen und lösen.
Bitte sagen Sie mir nicht, dass dies ein Fall von the XY problem ist: Ich weiß, dass ich nicht nach meinem tatsächlichen Problem frage, weil ich (und die Gemeinschaft) es für dieses Format für zu groß hielt.
Haben Sie "subtraktiv" versucht, den Code auszublenden, bis der Kompilierungsfehler verschwindet? Die andere Technik besteht darin, die problematische src-Datei vorzufunktionieren und einen großen Codeabschnitt auszugeben, bis er ohne diesen Fehler kompiliert wird. Ich nehme an, dass Sie eine Art Versionskontrolle für das einfache Zurücksetzen verwenden. – greatwolf