![](/img/trans.png)
[英]Why does std::copy() require std::back_inserter to insert into a vector with sufficient capacity?
[英]Why does std::vector::insert need to copy assign?
我試圖了解以下行為:
#include <vector>
#include <iterator>
struct Foo {
Foo(int a) : a_ {a} {}
const int a_; // Note the const
};
int main(int argc, char **argv) {
std::vector<Foo> v1 {Foo {0}};
std::vector<Foo> v2 {Foo {1}};
auto first = std::begin(v2);
auto last = std::end(v2);
for (; first != last; ++first) {
v1.push_back(*first); // Fine
}
//v1.insert(v1.begin(), first, last); // Does not compile
return 0;
}
事實證明, Foo
的const
成員隱式刪除了Foo
的復制賦值運算符,使用了std::vector::insert
。
為什么std::vector::insert
需要在std::vector::push_back
復制構造時復制assign? 這是否意味着手動連接兩個向量可能更有效? 這是使用LLVM。
從邏輯上講,沒有理由要求賦值運算符。 insert
操作可以完全通過使用(大致) vec[x+1].~T(); new(&vec[x+1]) T(std::move(vec[x]));
將任何現有元素vec[x]
到vec[x+1]
來實現vec[x+1].~T(); new(&vec[x+1]) T(std::move(vec[x]));
vec[x+1].~T(); new(&vec[x+1]) T(std::move(vec[x]));
在循環中銷毀現有元素,並使用就地構造來向前移動前一個元素。
然而,一種更自然的寫入方法,在設計良好的類中通常至少同樣有效,如果不是更有效,則使用賦值: vec[x+1] = std::move(vec[x]);
。 一個簡單的例子,它可以提高效率,如果向量元素的構造和破壞涉及分配和釋放內存:使用賦值可以輕松繞過它。
做出了一個決定,允許向量使用賦值運算符比缺點有更多的好處。 你的課很不尋常,你的課不會從這個決定中受益。 這很不幸,但是沒有辦法設計出適合每個用例的矢量。
要在向量中插入元素,如果它不是結尾,則應移動所有尾部元素
[1][2][3][4][5]
| | | \ \
[1][2][3][6][4][5]
因此,需要移動或復制構造函數。
http://en.cppreference.com/w/cpp/container/vector/insert
你仍然可以將循環轉換為
copy(first, last, back_insterter(v1))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.