2016-05-12 19 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)。

的选项有:

  • 重新设计你的代码不这样做
  • 使用不支持此