簡體   English   中英

當第一個向量重新分配時,另一個向量內的std :: vectors會重新分配嗎?

[英]Will std::vectors inside another vector reallocate when the first vector reallocates?

我有一個矢量std::vector<std::vector<ContactPairs>> m_contactPairs;

如果我調用m_contactPairs.push_back()或任何其他將調整最外層向量的函數,那么該向量內的元素是否必須重新分配(在這種情況下內部元素是std::vector<ContactPairs> ),或者是內部向量只做一個淺拷貝並繼續指向他們已經擁有的相同內存?

我使用的是先前的C ++ 11 Visual Studio 2010,但它具有一些擴展功能

簡短回答:這取決於您使用的標准和庫實現:

  • 在C ++ 98和C ++ 03中沒有任何移動,因此一切都將被深深復制,包括重新分配。
  • 在C ++ 11和C ++ 14會有包括重新分配的深層副本,或者,如果該實現提供了noexcept上的移動構造函數std::vector<ContactPairs>
  • 在即將到來的C ++ 17中,內部向量將被移動,不會執行深度復制。

這是推理:

  1. 內載體類型std::vector<ContactPairs>具有移動構造,其是noexcept根據即將到來的C ++ 17標准(如N4296的),而不是 noexcept根據C ++ 11和C ++ 14個標准,部分[vector.modifiers]。 你也可以在這里找到它。 但是,即使符合C ++ 11和C ++ 14的實現也可以指定noexcept ,因為實現可以提供比標准規定的更強的保證(參見C ++標准17.6.5.12)。 但是,許多實現方法並沒有這樣做。

  2. std::vector<T>::push_back()是保證強異常安全性所必需的,即如果它拋出則沒有副作用。 (參見C ++標准,[container.requirements.general]部分§10或§11或此處 。)

  3. 如果調用push_back()的向量的新大小超過其容量,則需要為新位置分配內存,並且需要復制元素或將其移動到新位置。 如果移動外部向量的元素可能失敗(沒有noexcept ),則需要復制元素以實現強異常保證。 在這種情況下,內部向量的每個副本需要額外的分配。 但是,如果移動是noexcept ,則整個移動循環不能拋出並且可以安全地用於實現強異常保證。

使用noexcept保證實現std::vector<T>移動構造似乎對std::vector是一件微不足道的事情。 我懷疑,標准委員會可能會猶豫是否將此保證放入標准中以保持一致性:對於其他基於節點的容器,具有標記節點可能是有益的,即使對於默認構造也需要分配。 由於移動后的容器需要在移動后有效,因此可能會有一個std::list移動所需的分配,例如。 因此, std::list和其他基於節點的標准容器類型的移動構造函數沒有noexcept保證。

在C ++ 03中, std::vector重新分配將復制 (“深層復制”)每個元素。 這意味着對於您的情況,每個向量都將被復制。

在C ++ 11或更高版本中, 僅當元素具有noexcept的移動構造函數時, std::vector重新分配才會移動每個元素。

Visual Studio 2010缺少noexcept支持,因此您仍然可以獲得深層副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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