[英]Forward declaration of objects with STL containers
Consider the following code snippet, where the first line serves only as forward declaration 请考虑以下代码段,其中第一行仅用作前向声明
class A;
followed by defining new class 然后定义新类
class B
{
vector<A> Av; //line 1
map<int, A> Am; //line 2
pair<int, A> Ap; //line 3
};
line 1 and line 2 seems to be fine with the forward declaration (which may tell me that those container use pointer type of implementation) where as line 3 does not seem to compile on VS2012. 第1行和第2行似乎没有前向声明(这可能告诉我那些容器使用指针类型的实现),其中第3行似乎不在VS2012上编译。
My question is that behavior dictated by the standard or specific to the compiler I am using? 我的问题是标准或特定于我正在使用的编译器所规定的行为?
Thanks 谢谢
The relevant rules for the standard library types are in [res.on.functions]: 标准库类型的相关规则在[res.on.functions]中:
In particular, the effects are undefined in the following cases: [...] if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.
特别是,在以下情况下,效果未定义:[...]如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件。
This: 这个:
vector<A> Av;
is fine. 很好。
std::vector
is allowed to be instantiated with an incomplete type, as long as it becomes complete before you use any of the members. 允许
std::vector
使用不完整类型进行实例化,只要它在您使用任何成员之前完成即可。 There is an explicit exception for this in the standard in [vector.overview]: 在[vector.overview]中的标准中有一个明确的例外:
An incomplete type
T
may be used when instantiatingvector
if the allocator satisfies the allocator completeness requirements 17.6.3.5.1.如果分配器满足分配器完整性要求17.6.3.5.1,则在实例化
vector
时可以使用不完整类型T
T
shall be complete before any member of the resulting specialization of vector is referenced.在引用向量特化的任何成员之前,
T
应该是完整的。
There is similar wording for std::list
and std::forward_list
. 对于
std::list
和std::forward_list
有类似的措辞。
This: 这个:
map<int, A> Am;
is ill-formed. 是不正确的。
std::map
requires a complete type at point of instantiation as per the first quote. 根据第一个引用,
std::map
在实例化时需要一个完整的类型。 There is no exception for this container in the way that there is for vector
. 这个容器没有例外,就像
vector
。
This: 这个:
pair<int, A> Ap;
cannot possibly ever work, since pair
is just a simply struct with two members. 不可能工作,因为
pair
只是一个有两个成员的简单结构。 In order to have a member of type A
, you need a complete type. 要拥有
A
类成员,您需要一个完整的类型。
[ As supplemental instruction to Barry's answer ] [ 作为对巴里答案的补充指导 ]
According to the standard (C++17), only std::vector
, std::list
and std::forward_list
could be used with incomplete type when instantiating. 根据标准(C ++ 17),在实例化时,只有
std::vector
, std::list
和std::forward_list
可以与不完整类型一起使用。
§23.3.11.1/3 Class template vector overview [vector.overview] : §23.3.11.1/ 3类模板向量概述[vector.overview] :
An incomplete type
T
may be used when instantiatingvector
if the allocator satisfies the allocator completeness requirements [allocator.requirements.completeness].如果分配器满足分配器完整性要求[allocator.requirements.completeness],则在实例化
vector
时可以使用不完整类型T
T
shall be complete before any member of the resulting specialization ofvector
is referenced.在引用
vector
任何成员之前,T
应该是完整的。
§23.3.9.1/4 Class template forward_list overview [forwardlist.overview] : §23.3.9.1/ 4类模板forward_list概述[forwardlist.overview] :
An incomplete type
T
may be used when instantiatingforward_list
if the allocator satisfies the allocator completeness requirements [allocator.requirements.completeness].如果分配器满足分配器完整性要求[allocator.requirements.completeness],则在实例化
forward_list
时可以使用不完整类型T
T
shall be complete before any member of the resulting specialization offorward_list
is referenced.在引用
forward_list
成员的任何成员之前,T
应该完成。
§23.3.10.1/3 Class template list overview [list.overview] : §23.3.10.1/ 3类模板列表概述[list.overview] :
An incomplete type
T
may be used when instantiatinglist
if the allocator satisfies the allocator completeness requirements [allocator.requirements.completeness].如果分配器满足分配器完整性要求[allocator.requirements.completeness],则在实例化
list
时可以使用不完整类型T
T
shall be complete before any member of the resulting specialization oflist
is referenced.在引用
list
专有化的任何成员之前,T
应该是完整的。
Nope, this behavior is expected and standard. 不,这种行为是预期的和标准的。
The rational is that std::pair actually forms a struct, therefore both its types must be complete before instantiation. 理性的是std :: pair实际上形成了一个结构,因此它的类型必须在实例化之前完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.