在test.h
向前申報值分配類給我一個錯誤,struct Incomplete
是我在前面聲明的寫g++ main.cpp test.h -o main.o
。不能與在標準::地圖成員變量
但是,如果我將std::map<int, Incomplete> member
更改爲std::map<int, Incomplete*> member
,main.o
編譯。爲什麼是這樣?
在test.h
向前申報值分配類給我一個錯誤,struct Incomplete
是我在前面聲明的寫g++ main.cpp test.h -o main.o
。不能與在標準::地圖成員變量
但是,如果我將std::map<int, Incomplete> member
更改爲std::map<int, Incomplete*> member
,main.o
編譯。爲什麼是這樣?
這是爲什麼?
由於C++標準庫容器未定義爲使用不完整的成員類型。 This is by design - 但它可以說是一個錯誤(在將來的C++版本中可能會改變)。 Boost.Containers庫修復了這個問題。
帶指針的代碼可以工作,因爲指向不完整類型的指針本身就是一個完整類型。然而,這會明顯地改變你類型的語義(尤其是誰來管理內存?),並且用它作爲替代品通常不是一個好主意。
值得指出的是,文章稱,你在技術上無法實現std::map
使用不完全類型的工作。但是,這種說法是錯誤的。
當您轉發聲明一個類型時,您基本上聲明存在該名稱的類型,僅此而已。編譯器不知道它的大小,成員等等。它被稱爲不完整類型,除了聲明指針或引用外,不能用於其他任何內容。這是可能的,因爲指針的大小,而不管它的類型在同一個平臺上是相同的。
正向聲明意味着「這個類/結構/不管將在代碼後面」。那個容器需要知道結構有多大的內存記錄。從技術角度而言,您正在使用不完整類型。因爲在大多數機器上指針的大小是固定的(x64通常有8個字節的指針),所以在編譯時你不需要看到結構的完整定義,因爲你不需要「計算」很多空間可以在地圖上保留該結構:您只需要指針所需的空間。
你說得對,那句話是錯的。我會編輯它。 –