正文 直接說答案,這個問題無法實現。原因是因為std::vector容器的插入一定會調用類對象的構造函數或者移動構造函數。 說一下為什麼會有這個問題,因為不想用指針,我想直接通過類對象本身的RAII機制來實現的資源的控制,智能指針是一個解決方案,不過智能指針是寫起來很繁瑣,終究比不上值類型方便。不過 ...
正文
直接說答案,這個問題無法實現。原因是因為std::vector容器的插入一定會調用類對象的構造函數或者移動構造函數。
說一下為什麼會有這個問題,因為不想用指針,我想直接通過類對象本身的RAII機制來實現的資源的控制,智能指針是一個解決方案,不過智能指針是寫起來很繁瑣,終究比不上值類型方便。不過值類型要用好還是很麻煩的,比如這裡的將沒有複製或移動構造函數的對象插入到std::vector容器中的問題。
經過查閱資料,總共有四種解決方案:
- 使用預設構造函數,並且初始化時確定容器大小。例如:
int num = 23; std::vector<std::mutex> vec(num);
- 將std::vector容器中的元素改成智能指針std::unique_ptr。
- 更換容器,使用std::deque。
- 更換容器,std::list/forward_list。
第一種方案比較有局限性,不僅要求使用預設參數,還要求預先確定容器大小。使用智能指針的方案還是不錯的,只要你願意使用智能指針的語法。筆者這裡使用的時第三種,更換容器為std::deque。
std::deque是雙端隊列,和std::vector相比,其記憶體存儲不是連續的,但是也不像std::list是那種完全碎片化的記憶體,是一小塊連續空間連著一小塊連續空間進行存儲的。因此,在插入時std::deque不像std::vector那樣需要移動或者拷貝構造,是直接初始化構造在分配的空間中的。
基於這個原理,std::deque的隨機訪問、在尾部和首部插入和刪除的速度都很快,時間複雜度都為O(1)。如果不是有特別的需求,可以使用std::deque代替std::vector。
參考
- How to store objects without copy or move constructor in std::vector?
- https://zhuanlan.zhihu.com/p/364408441