![](/img/trans.png)
[英]Does std::vector::insert() invalidate iterators if the vector has enough room (created through reserve)?
[英]Does std::vector::reserve guarantee that the implementation will not invalidate iterators in this case?
這是一個打算:
a)接受int的向量
b)對於輸入向量中的每個int,追加此int的逆
先決條件:無
postconditions:返回vector的size()是2 *輸入向量的大小。
請注意,矢量是就地修改的。
在變換期間,此函數是否嚴格定義了與迭代器失效相關的行為?
是否有更好/更簡潔/更健壯的方式來編寫它?
std::vector<int> append_negatives(std::vector<int> v)
{
v.reserve(v.size() * 2);
std::transform(begin(v), end(v),
back_inserter(v),
[](auto&& x) { return -x; });
return v;
}
只要您不超過預分配容量,就不會發生重新分配,也不會使引用矢量項的引用或迭代器失效。 但是,由於end()
返回的迭代器不引用任何向量項,因此它可能仍會失效。
23.3.11.3載體容量[vector.capacity]
- ...在調用
reserve()
之后發生的插入期間不應進行重新分配,直到插入使向量的大小大於capacity()
的值reserve()
為止
...
23.3.11.5向量修飾符[vector.modifiers]
- ...如果沒有重新分配,插入點之前的所有迭代器和引用仍然有效。
關於迭代器失效規則的部分已經被涵蓋了,所以我將借此機會謙虛地質疑是否需要使用所有這些機制(以其微妙的規則)來處理這樣一個微不足道的問題。 你也可以認為這是一個刺
獎金:
是否有更好/更簡潔/更健壯的方式來編寫它?
部分問題。
老實說,我完全用for
循環的先進技術來回避這個問題。 吻 !
std::vector<int> append_negatives(std::vector<int> v) {
size_t sz = v.size();
v.resize(sz*2);
for(size_t i = 0; i < sz; ++i) v[i+sz] = -v[i];
return v;
}
並非所有內容都必須在深層的STL算法中進行混淆。 這個更短,IMO更具可讀性,並避免了迭代器失效的麻煩。
此外,除非編譯器自上次檢查以來已經獲得了額外的智能,否則這要快得多,因為避免了push_back
所有開銷(檢查容量是否足夠以及每次迭代時的增量大小),這被替換為直接指針訪問( 一個程序集)指令); 纖細而簡單的環體為自動展開提供了更好的機會。 我希望編譯速度更快,因為我們避免實例化一堆模板。
請注意,即使使用transform
benemoth,也可以獲得速度優勢/無失效頭痛:
std::vector<int> append_negatives(std::vector<int> v) {
size_t sz = v.size();
v.resize(sz * 2);
auto beg = begin(v);
std::transform(beg, beg + sz, beg + sz,
[](int x) { return -x; });
return v;
}
但我沒有看到這種過於冗長的代碼優於普通for
循環的任何優勢,除非你得到你設法擠入代碼的“酷”C ++功能的數量。
@MikeMB詢問默認構造成本高昂的類型; 在這種情況下,顯式push_back
很好:
std::vector<int> append_negatives(std::vector<int> v) {
size_t sz = v.size();
v.reserve(sz*2); // optional
for(size_t i = 0; i < sz; ++i) v.push_back(-v[i]);
return v;
}
如果原始帖子中的transform
有效,您還可以使用基於范圍的for循環:
std::vector<int> append_negatives(std::vector<int> v) {
v.reserve(v.size()*2);
for(int &x: v) v.push_back(x);
return v;
}
這是對眼睛比基於變換的解決方式更好,但我有還是沒有關於結束迭代器失效一致的意見看,所以這將是同樣無效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.