簡體   English   中英

標准庫容器和不完整類型的規則是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM