给定一个不完整的类型:
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
明确地allowed使用不完整的类型。std::deque
似乎没有这样的允许.
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?
这实际上是这里有趣的一点。是的,实例化类型不完整的容器是不允许的,没有规定。但问题是它是否真的被实例化了。根据核心语言,它不一定是这样。
[温度设置]
1除非类模板特化已明确
实例化或显式专门化,类模板
当专业化是隐式实例化时
在需要完全定义的对象类型的上下文中引用
或者当类类型的完整性影响语义时
该程序。
指向类型的指针并不要求类型是完整的。因此,仅此声明通常不足以导致类模板的实例化,因此确定此处违反容器的要求可能为时过早。
当然除非我们采取“类类型的完整性影响程序的语义”将违反合同的行为纳入标准库中。一个实现could我想在这里实例化。然而,我不知道有任何实现,因此这可能不是所需的解释。
因此,为了谨慎起见,我也认为这个 UB 是正确的。
std::deque<S*> p; // not really sure about this one
这可以。无论是否S
做完了,S*
仍然是一个完整的对象类型。我这么说是因为它不包含在
[基本类型]
5已声明但未定义的类、枚举
在某些上下文中键入([dcl.enum]),或未知边界的数组或
不完整元素类型,是不完整定义的对象类型。
不完全定义的对象类型和 cv void 是不完全类型
([基本.根本])。对象不应被定义为具有
不完整类型。
完整性约束S
仅当尝试在执行取消引用或指针算术的表达式中使用此类指针时才会出现。但指针类型本身仍然是完整的。因此它是容器类型的有效模板参数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)