标准库容器和不完整类型的规则是什么? [英] What are the rules for standard library containers and incomplete types?

查看:90
本文介绍了标准库容器和不完整类型的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出不完整的类型:

struct S; 

那么以下声明是:

S *p;            // ok, pointer to incomplete types is allowed

std::deque<S> l;  // error, instantiating std::deque with incomplete type is UB

但是下面的声明呢?

std::deque<S> *p;   // seems to be UB like the previous case, 
                   // but is it ok if p is not used till S is defined?

std::deque<S*> p;   // not really sure about this one

问题使用了 std :: list 而不是 std :: deque ,但是由于 std :: list明确允许使用不完整的类型. std :: deque 似乎没有这样的权限.

the question used std::list instead of std::deque, but that defeats the purpose of the question, since std::list is explicitly allowed to use incomplete types. std::deque doesn't appear to have such permission.

推荐答案

std::deque<S> *p;   // seems to be UB like the previous case, 
                   // but is it ok if p is not used till S is defined?

这实际上是有趣的地方.是的,实例化不允许使用类型不完整的容器,但没有为此提供任何条件.但是问题在于它是否真的被实例化了.根据核心语言,不一定如此.

That's actually the interesting bit here. Yes, instantiating that container with an incomplete type is not allowed, there is no provision for it. But the question becomes whether or not it's really instantiated. It doesn't have to be, according to the core language.

[临时温度]

1 除非明确定义了类模板专业化实例化或显式专门化的类模板当专门化是在需要完全定义的对象类型的上下文中引用或类类型的完整性影响以下语言的语义时该程序.

1 Unless a class template specialization has been explicitly instantiated or explicitly specialized, the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program.

指向类型的指针不需要该类型是完整的.因此,仅靠此声明通常不足以实例化类模板,因此在这里确定是否违反了容器的要求可能为时过早.

A pointer to a type doesn't require the type to be complete. So this declaration alone is not normally enough to cause an instantiation of a class template, and so it may be premature to determine the requirement of the container is violated here.

除非我们当然采用类类型的完整性会影响程序的语义",否则将包含在标准库中.我想,实现可以在这里实例化.我不知道有什么实现的方法,因此这可能不是欲望的解释.

Unless of course we take "the completeness of the class type affects the semantics of the program" to include contract violations in the standard library. An implementation could instantiate here, I suppose. I'm not aware of any implementation that does however, so this may not be the desires interpretation.

所以要谨慎一点,我也认为这个UB.

So to err on to side of caution, I'd deem this UB too.

std::deque<S*> p;  // not really sure about this one

这很好.不管 S 是否完整, S * 仍然是完整的对象类型.我之所以这样说,是因为它不包含在

This is fine. Whether or not S is complete, S* is still a complete object type. I say this because it's not included at

[基本类型]

5 已声明但未定义的类,一个枚举在某些情况下([dcl.enum])键入,或未知范围或元素类型不完整的,是对象定义不完整的类型.不完全定义的对象类型和cv void是不完全类型([basic.fundamental]).对象不应定义为具有类型不完整.

5 A class that has been declared but not defined, an enumeration type in certain contexts ([dcl.enum]), or an array of unknown bound or of incomplete element type, is an incompletely-defined object type. Incompletely-defined object types and cv void are incomplete types ([basic.fundamental]). Objects shall not be defined to have an incomplete type.

关于 S 完整性的约束仅在尝试在执行解引用或指针算术的表达式中使用此类指针时出现.但是指针类型本身仍然是完整的.因此,这是容器类型的有效模板参数.

The constraints about the completeness of S only appear when attempting to use such a pointer in an expressions that does a dereference or pointer arithmetic. But the pointer type itself is still complete. So it's a valid template argument for a container type.

这篇关于标准库容器和不完整类型的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆