簡體   English   中英

從原始數據就地創建std :: vector

[英]Create std::vector in-place from raw data

給定一個原始數組元素,如何創建一個std::vector ,它獲取原始數組的所有權而無需重新分配和復制?

例如,具有原始數組:

int* elems = new int[33]

如何創建一個大小為33std::vector指向elems

我確信理論上這是可能的,因為通常std::vector被實現為包含三個指針的結構,一個指向已分配內存的開頭,一個指向有效元素的末尾,一個指向結尾分配內存。 但是有沒有一種標准方法用原始數組初始化std::vector結構?

你需要的是一個“視圖”而不是一個容器。 容器擁有它們的元素,它們的主要目的是封裝它們管理的原始內存。 如果您需要自己管理內存,那么您不需要容器。 如果您有一個string ,請查看string_view ,這將是您的解決方案。 也許你可以應用提升范圍 從文檔(強調我的):

Range概念的動機是有許多有用的類似容器的類型不能滿足Container的全部要求,並且許多算法都可以用這個減少的要求集來編寫。 特別是,Range不一定

  • 擁有可以通過它訪問的元素
  • 有復制語義,

PS:實際上std::array_view被認為是C ++ 17,但遺憾的是它並沒有成為標准。

這不能直接實現的原因是標准庫使用分配器為容器保留內存。

因此,如果你有一個使用某種類型的分配器的std::vector並給它一些你創建的指針,你就會有效地打破分配器的習慣用法。 例如,如果您的標准庫的實現使用mallocfree而不是newdelete ,那么您的程序將失敗。

為了使其成為標准方式 ,標准庫需要提供一個接受T*的構造函數,該T*還必須由向量稍后使用的相同分配器返回。 所以你需要的構造函數的簽名就像std::vector::vector(T* data, size_type used_elements, size_type capacity, const Allocator& alloc) 請注意,allocator參數是必需的,因為T*必須(理論上)由向量中使用的完全相同的分配器返回。


您可以通過根據此概念創建自己的分配器來實現 某些功能 ,但是為了不重構您的33元素,您還必須提供allocator::construct(..)函數,這是一個無操作直到第34th元素(獨家)。 此外,您必須首先將矢量調整為33元素,以強制矢量具有正確的大小。

盡管如此,這是一個壞主意,因為對於條件構造和分配函數,您可能會有更多的開銷,而不是復制元素一次。

根據這一點 ,沒有構造函數接受指向數據的指針。 因此,您無法將原始數組的所有權傳遞給向量。

您只能創建一個向量並將數據放入其中。

給定一個原始數組元素,如何創建一個std::vector ,它獲取原始數組的所有權而無需重新分配和復制?

沒有辦法。

如何創建一個大小為33的std::vector指向elems?

不可能。

我確信理論上這是可能的,

不,不是。

但是有沒有一種標准方法用原始數組初始化std::vector結構?

沒有。


話雖如此,您可能能夠使用自定義分配器將解決方案混合在一起。 但是,除了編寫自定義分配器是一種很少使用的容易出錯的技術之外,您不應該高估這種解決方案的可用性。

std::vector<int>std::vector<int, MyAllocator>兩個不同的類 如果你的目標是與期望std::vector<int>代碼接口,那么就不能使用std::vector<int, MyAllocator> ; 如果你打算在你的代碼中創建和使用std::vector<int, MyAllocator> ,那么老實說你最好只是實現你自己的非擁有容器類,比如自定義VectorView<T>

如果您正在處理的對象的類型是可移動的,則可以執行以下操作:

template<typename T>
std::vector<std::unique_ptr<T>> ConvertArrayToVector(T* data, size_t size)
{
    std::vector<std::unique_ptr<T>> result(size);
    for (unsigned int i = 0; i<size; ++i)
        result[i] = std::make_unique<T>(std::forward<T>(data[i]));

    return result;
}

結果向量現在擁有該數組,從某種意義上說,它存儲指向其元素的指針,並確保在向量被銷毀時刪除對象,但原始數組在此過程中失效。

暫無
暫無

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

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