2016-05-12 46 views
2

我已經用C++編寫了一個與clang ++編譯的程序,但不是用g ++編譯的,我想理解爲什麼。在該類聲明中的STL容器控制類

的重要組成部分是:

class Table { 
    private: 
     ... 
     std::unordered_map<std::string,Table> table_map; 
     ... 
}; 

我認爲的std :: unordered_map會使用指針「引擎蓋下」,所以,這是合法的。我沒有在Table中聲明一個Table,但是我創建了一個容器,它有一個指向Table內的Table的指針。或者我想。鏗鏘聲++沒有問題,程序運行良好。

但是,g ++抱怨這個,說「note: forward declaration of 'class Table'」。這表明我應該明確地讓std :: unordered_map採取一個指針(std::unordered_map<std::string,Table*>,或者可能有些智能指針的味道)。這需要我做一些額外的工作(而且我正在處理一年前寫的代碼,所以我不急於弄清楚爲了做出必要的更改而做了什麼)。

這是g ++中的一個bug還是clang ++做了一些聰明的事情,這不是標準的一部分?有沒有更好的方法來重寫這段代碼,以便在clang ++和g ++上編譯?

我有另一個名爲Value的類,並且表中有一個std :: unordered_map值,所以我可以通過創建一個超類元素來解決此問題,Value和Table都從中繼承,然後讓表包含std::unordered_map<std::string,Element> ?或者,這樣的地圖無法存儲值和表,因爲它是爲元素聲明的?

+4

有對'的std :: VECTOR',標準計劃的容器庫: :list'和'std :: forward_list'來支持不完整的類型,但不支持'std :: unordered_map'。也許Boost的地圖支持它。 – chris

回答

4

錯誤是由std :: unordered_map必須重新哈希表然後複製元素造成的。存儲在容器中的值因此必須是完整的類型。

您可以通過包裝值轉換成智能指針挺過來了:

#include <iostream> 
#include <string> 
#include <unordered_map> 
#include <memory>   // shared_ptr 

class Table { 
    private: 
    std::unordered_map<std::string, std::shared_ptr<Table> > t; 
}; 

int main() { 
    Table t; 
    return 0; 
} 

Compiles

+0

'unique_ptr

'當然也是可以的 –

2

這是未定義的行爲。標準庫容器不能用不完整類型實例化,除非它明確表示容器支持它(例如unique_ptr)。

的選項有:

  • 重新設計你的代碼不這樣做
  • 使用不支持此