我很困惑爲什麼我的代碼不會產生錯誤invalid use of incomplete type
,而我對這個錯誤所做的所有閱讀都表明它應該這樣做。
的問題,從這個錯誤朵朵顯示出來(如預期)中的我具有相似結構的代碼的一部分,但我不能在小例如複製它(請參閱免責聲明在的結束題)。不完整類型的使用無效 - 爲什麼在這種情況下沒有錯誤?
總結一下我試圖做的事:
- 我有一個結構(
Tree
),我想基本類型First
的不同對象分配給它。 - 的
First
具體實現具有不同的返回值,因此間接兩個級別被使用: First
是一個抽象基類,和First *
用來處理不同的具體實例。template <typename Type> class TypedFirst : public First
是一種抽象類型,它定義了返回類型爲Type
的函數。- 最後
ConcreteFirstX
是TypedFirst<Type>
的具體特化。
在tree.tpp
,爲什麼調用new TF(this)
不產生invalid use of incomplete type
錯誤? (該點在代碼中標出)我認爲錯誤應該在那裏,因爲,雖然TF
是模板,但是當我使用ConcreteFirstA
時,tree.tpp
不知道它(它不包括concretefirsta.h
或甚至first.h
,它只有,它只有正向聲明First
)
此示例的完整,可編譯和可運行的代碼可以找到here on pastebin。在這裏,爲了簡潔,我將排除#define
警衛和類似的事情。代碼如下:
// 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";
最後,一起帶來了這一切,使得(中)適當的函數調用的代碼:
// 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;
}
免責聲明這個問題實際上是由我遇到的一個更大的問題所驅動的,我認爲它在堆棧溢出格式中太大而無法回答。儘管我最初試圖提出這個問題,但問題已經過於廣泛了,我現在試圖通過詢問問題的一部分來解決問題。
我的問題是,我一直在一個與這個結構相同的代碼片段中收到錯誤:但是,我不能在一個小例子中重現它。
因此,我問爲什麼下面這段代碼是不產生錯誤invalid use of incomplete type
(如我所期望的),我希望這將有助於我瞭解並解決我的實際問題。
請不要告訴我,這是一個the XY problem的案例:我知道我並不是在問我的實際問題,因爲我(和社區)認爲這個格式太大了。
您是否嘗試'減法'切割代碼,直到編譯錯誤消失?另一種技術是對有問題的src文件進行預處理,然後開始對大量代碼進行樁化處理,直到編譯時沒有出現錯誤。我假設你正在使用某種版本控制來簡化回滾。 – greatwolf 2014-12-24 07:56:32