![](/img/trans.png)
[英]Why are only these C++ standard library containers guaranteed to allow incomplete types?
[英]What are the rules for standard library containers and incomplete types?
給定一個不完整的類型:
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
似乎沒有這樣的權限。
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?
這實際上是這里有趣的一點。 是的,不允許使用不完整類型實例化該容器,沒有任何規定。 但問題是它是否真的被實例化了。 根據核心語言,它不一定是。
[溫度.inst]
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程序。
指向類型的指針不需要類型是完整的。 因此,僅此聲明通常不足以導致 class 模板的實例化,因此確定此處違反容器的要求可能為時過早。
當然,除非我們將“class 類型的完整性影響程序的語義”納入標准庫中的合同違規。 我想,一個實現可以在這里實例化。 但是,我不知道有任何實現,因此這可能不是期望的解釋。
所以為了謹慎起見,我也認為這個 UB。
std::deque<S*> p; // not really sure about this one
這可以。 不管S
是否完整, S*
仍然是一個完整的 object 類型。 我這樣說是因為它不包含在
[基本類型]
5已聲明但未定義的 class、某些上下文中的枚舉類型 ([dcl.enum]) 或未知邊界或不完整元素類型的數組是未完全定義的 object 類型。 未完全定義的 object 類型和 cv void 是不完全類型([basic.fundamental])。 對象不應被定義為具有不完整的類型。
僅當嘗試在執行取消引用或指針算術的表達式中使用此類指針時,才會出現有關S
完整性的約束。 但是指針類型本身還是完整的。 所以它是容器類型的有效模板參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.