2011-12-07 38 views
1

以下是根據http://www.sgi.com/tech/stl/copy.html複製的定義。STL複製執行

template<class InputIterator, class OutputIterator> 
    OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result) 
{ 
    while (first != last) *result++ = *first++; 
    return result; 
} 

我寫了下面的代碼。

vector<int> v; 
set<int> s; 

s.insert(7); 
s.insert(11); 
s.insert(27); 

//copy elements from the set into the vector 
copy(s.begin(), s.end(), v.begin()); 

爲什麼上面複製的調用會生成運行時錯誤而不是編譯錯誤?我假設它與向量爲空的事實有關,v.begin()== v.end()。但爲什麼?

此外,我通過將其更改爲以下來修復了該代碼。

copy(s.begin(), s.end(), back_inserter(v)); 

函數back_inserter返回類型爲back_insert_iterator>的迭代器。爲什麼這個工作?它在做什麼?

回答

2

,因爲你不尊重這個相同的網站上列出的第三個前提它失敗:

有足夠的空間來容納所有的元素被複制。更多 正式的,要求是[result,result +(last - first))是 的有效範圍。 [1]

空向量小於一組3個元素,因此您無法執行復制操作(實際上應該稱爲「覆蓋」操作)。這些信息在編譯時是不知道的,因此沒有編譯時失敗。請記住,雖然向量和大多數其他C++ STL集合在運行時可擴展,但它們不能通過常規迭代器操作(主要用於枚舉項目和指定範圍)進行擴展。

back_inserter函數返回一個特殊的迭代器,它將插入元素到集合的末尾。這個迭代器是一個輸出迭代器,與通過向量的begin()end()方法獲得的迭代器很少有關。您無法從輸出迭代器中讀取數據。

0

想想數組的簡單情況 - 使用迭代器的指針。現在,設想s和v是數組。如果s有3個元素和v 0,並且您試圖將s複製到v中,則它不起作用。如果v有3個元素,則複製將起作用,覆蓋當前內容。

STL中的迭代器模型是對此的推廣。實際上,指針可以用作迭代器,但其他對象也可以使用(可以使用指向數組第一個元素的指針調用copy,而指針則可以剛好超過結尾並且它可以工作)。因此,它不起作用的原因完全相同。

back_inserter是一個用於這種情況的迭代器;而不是通過集合覆蓋當前位置,它增加了集合的大小(當然這必須是一個可以增長的集合,如向量)並寫入新的位置。