![](/img/trans.png)
[英]Assign std::vector<std::unique_ptr<T>> to another std::vector<std::unique_ptr<T>>
[英]Move std::vector<std::unique_ptr<T>> to std::vector<std::shared_ptr<T>>
有時我們有一個工廠生成std :: unique_ptr的向量,稍后我們想在類/線程/你之間共享這些指針。 因此,最好使用std :: shared_ptr。 有一種方法可以將std :: uniqe_ptr轉換為std :: shared_ptr
std::shared_ptr<int> sharedV;
std::unique_ptr<int> uniqueV(new int(2));
sharedV = std::move(uniqueV);
那么有什么簡單的方法來用std集合做這樣的事情嗎?
您可以使用std::move
from <algorithm>
來移動范圍。 它的行為與std::copy
非常相似,但相反。 以下示例將所有unique_ptr
從uniqueV
移動到sharedV
。 uniqueV
的元素在示例的末尾都將為nullptr
。
#include <algorithm>
#include <iterator>
#include <memory>
#include <vector>
int main()
{
std::vector<std::shared_ptr<int>> sharedV;
std::vector<std::unique_ptr<int>> uniqueV;
uniqueV.emplace_back(std::make_unique<int>(42));
std::move(uniqueV.begin(), uniqueV.end(), std::back_inserter(sharedV));
return 0;
}
為了補充FrançoisAndrieux的答案 , std::vector
有一個ranged insert()
成員函數。 只是將迭代器傳遞給unique_ptr
的向量將無法正常工作,但有一種方法可以將這些迭代器的解除引用從lvalues轉換為xvalues: std::move_iterator
及其相應的工廠函數: std::make_move_iterator
:
sharedV.insert(sharedV.end(),
std::make_move_iterator(uniqueV.begin()),
std::make_move_iterator(uniqueV.end()));
這可能比使用std::back_inserter
更有效的原因是insert()
將預先知道結果大小將是什么,因此只需要完成一個分配,然后實際插入都不需要做大小檢查。
這寫起來很尷尬我會建議這個名為extend()
的基於范圍的重載:
template <class T, class Range>
void extend(std::vector<T>& dst, Range&& range) {
using std::begin; using std::end;
if constexpr (std::is_lvalue_reference<Range>{}) {
dst.insert(dst.end(), begin(range), end(range));
} else {
dst.insert(dst.end(),
std::move_iterator(begin(range)), std::move_iterator(end(range)));
}
}
這是C ++ 17,但在C ++ 14中很容易實現。 只需輸入更多內容。 然后你會寫:
extend(sharedV, std::move(uniqueV));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.