2011-03-06 61 views
2

我想了解STL算法。STL - 複製混合容器

複製的定義是:

template<class InputIterator, class OutputIterator> 
    OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result) 

能有人請解釋爲什麼當載體&雙端混合了以下工作,但是當載體和臺混合失敗。

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <deque> 
#include <deque> 
#include <set> 
using namespace std; 

int main() { 
    int myints[]={10,20,30,40,50,60,70}; 
    vector<int> myvector; 
    vector<int>::iterator it; 

    set<int> mset(myints,myints+8); 
    set<int>::iterator setItr = mset.begin(); 




    deque<int> deq; 
    deq.resize(10); 
    deque<int>::iterator deqItr = deq.begin(); 
    myvector.resize(7); // allocate space for 7 elements 
    copy (myints, myints+7, myvector.begin()); 

    copy (myvector.begin(), myvector.end(), deqItr); 
    cout << "deque contains:"; 
    for (deque<int>::iterator dit=deq.begin(); dit!=deq.end(); ++dit) 
    cout << " " << *dit; 

    cout << endl; 

    //copy (myvector.begin(), myvector.end(), setItr); 


    return 0; 
} 

據我所知,vector/deque有隨機訪問迭代器,其中set有雙向迭代器。我不明白爲什麼當只需要輸入/輸出迭代器時編譯失敗。

PS:這只是一項實驗,以提高我的理解:)

回答

5

關聯容器(普通的C++ 03)是特殊的容器,它們的元素始終保持排序,通常實現爲紅黑樹。爲了保持順序不變,集合和映射迭代器爲關鍵對象提供常量引用,因此您不能對其進行修改。

特別是對於std::set<T>,迭代器通常會使std::iterator_traits< std::set<T>::iterator >::referenceconst T&,因此在std::copy操作中隱含的分配將失敗。

如果你想要做的是插入的元素爲一組,你可以使用迭代從<iterator>頭,將在集執行insert操作:

std::copy(v.begin(), v.end(), std::inserter(s, s.end())); // s is the set 
+0

感謝您的解釋,由於排序問題,它是有意義的。 – 2011-03-06 19:40:49

5

std::vectorstd::deque有一種方式來預分配的空間。 std::set沒有。如果不預先分配空間,嘗試取消引用您傳遞給copy的迭代器會產生未定義的行爲。

明顯的替代方法是使用插入迭代器代替 - 雖然,不幸的是,你仍然需要 幾乎 總是使用不同的代碼爲一組比雙端隊列或向量:

std::copy(myvector.begin(), myvector.end(), std::back_inserter(mydeque)); 

std::copy(myvector.begin(), myvector.end(), std::inserter(mySet, mySet.end()); 
+0

你並不真的需要不同的代碼,第二種方法對'set'和'deque'(或'vector','list' ...):'std :: copy(src.begin(),src.end(),std: :inserter(dst,dst.end()));'可以與兩者一起使用。 – 2011-03-06 19:44:13

+0

我不明白爲什麼需要預先分配。這是爲了避免由於傳遞沒有分配內存的迭代器而導致的錯誤?例如:如果我要刪除調整大小並將其傳遞給副本,它最終會成爲seg故障。即預先分配沒有幫助。我錯過了什麼嗎? – 2011-03-06 19:47:19

+0

@David:你說得對 - 「需要」是錯誤的詞。 「幾乎總是使用」會更準確。 – 2011-03-06 19:54:17

0

它的工作原理爲載體,因爲你可以預先分配空間。對於其他容器,比如map,你需要一個迭代器適配器來爲你做。例如,查看insert_iterator。