使用STL容器转发对象的声明

时间:2016-08-11 14:17:39

标签: c++ visual-studio-2012 stl forward-declaration std-pair

请考虑以下代码段,其中第一行仅用作前向声明

 class A;

然后定义新类

class B
{
 vector<A> Av;  //line 1
 map<int, A> Am;  //line 2
 pair<int, A> Ap; //line 3
};

第1行和第2行似乎没有正确的声明(这可能告诉我那些容器使用指针类型的实现),而第3行似乎没有在VS2012上编译。

我的问题是标准或特定于我正在使用的编译器所指示的行为?

由于

3 个答案:

答案 0 :(得分:11)

标准库类型的相关规则在[res.on.functions]中:

  

特别是,在以下情况下效果未定义:[...]如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件。

此:

vector<A> Av;

很好。允许std::vector实例化为不完整类型,只要它在您使用任何成员之前完成即可。在[vector.overview]的标准中有一个明确的例外:

  

如果分配器满足分配器完整性,则在实例化T时可以使用不完整类型vector   要求17.6.3.5.1。 T之前应在向量专业化的任何成员之前完成   被引用。

std::liststd::forward_list有类似的措辞。

此:

map<int, A> Am;

是不正确的。根据第一个引用,std::map在实例化时需要一个完整的类型。这个容器没有例外vector

此:

pair<int, A> Ap;

不可能工作,因为pair只是一个有两个成员的简单结构。要拥有A类型的成员,您需要一个完整的类型。

答案 1 :(得分:5)

[作为Barry回答的补充说明]

根据标准(C ++ 17),实例化时,只有std::vectorstd::liststd::forward_list可用于不完整类型。

§23.3.11.1/3 Class template vector overview [vector.overview]

  

如果分配器满足分配器完整性要求[allocator.requirements.completeness],则在实例化T时可以使用不完整类型vector。在引用T的结果专业化的任何成员之前,vector应完成。

§23.3.9.1/4 Class template forward_list overview [forwardlist.overview]

  

如果分配器满足分配器完整性要求[allocator.requirements.completeness],则在实例化T时可以使用不完整类型forward_list。在引用T的结果专业化的任何成员之前,forward_list应完成。

§23.3.10.1/3 Class template list overview [list.overview]

  

如果分配器满足分配器完整性要求[allocator.requirements.completeness],则在实例化T时可以使用不完整类型list。在引用T的结果专业化的任何成员之前,list应完成。

答案 2 :(得分:2)

不,这种行为是预期和标准的。

理性是URLEmbeddedView实际上形成了一个结构,因此它们的类型必须在实例化之前完成。