對于copy配合iterator來輸出一些容器的便利性是非常喜歡的,但是copy在處理map容器的時候,很容易導致編譯出錯,問題代碼如下:
1 ostream& operator << (ostream& out, const pair<const int,int>& value)
2 {
3 out<<"("<<value.first<<","<<value.second<<")";
4 return out;
5 }
6 int main()
7 {
8 map<int, int> imap;
9 for(int i=0;i<10; ++i)
10 {
11 imap.insert( map<int,int>::value_type(i, i*10) );
12 }
13 copy(imap.begin(), imap.end(), ostream_iterator<pair<const int, int> >(cout,","));
14 cout<<endl;
15 }
這個問題的起因:在遇到key和value為內置類型或std::類型的時候,編譯器無法找到用戶自定義的operator <<操作符。在處理上述代碼時,編譯只會在std里查找pair的operator <<定義。
解決的辦法:
1.使用非內置類型和非std::類型。
2.使用transform函數取代copy函數。
對于第一種解決方法,我們只用重封裝一下就可以:
1 struct MyType
2 {
3 int value;
4 };
5
6 ostream& operator << (ostream& out, const pair<const int, MyType>& value)
7 {
8 out<<"("<<value.first<<","<<value.second.value<<")";
9 return out;
10 }
11
12 int main()
13 {
14 map<int, MyType> imap;
15 for(int i=0;i<10; ++i)
16 {
17 MyType tmp = { i*10 };
18 imap.insert( map<int, MyType>::value_type(i, tmp) );
19 }
20
21 copy(imap.begin(), imap.end(), ostream_iterator<pair<const int, MyType> >(cout,","));
22 cout<<endl;
23 }
對于第二種方法,則必需要寫一個toString的函數來把pair的數據處理一下:
1 ostream& operator << (ostream& out, const string& str)
2 {
3 return out<<str;
4 }
5
6 string toString(const pair<const int, int>& value)
7 {
8 ostringstream ost;
9 ost<<"("<<value.first<<","<<value.second<<")";
10 return ost.str();
11 }
12
13 int main()
14 {
15 map<int, int> imap;
16 for(int i=0;i<10; ++i)
17 {
18 imap.insert( map<int,int>::value_type(i, i*10) );
19 }
20
21 transform(imap.begin(), imap.end(), ostream_iterator<string>(cout, " "), toString);
22 cout<<endl;
23 }
除此之外,如果我們采用了第一種方法,自己定義了一個結構體,作為map的value來作用,希望通過copy函數能直接輸出相應的內容。那么我們一般會先定義一個結構體的operator <<操作:
1 namespace TEST_NS{
2
3 struct Info{
4 unsigned int Value;
5 };
6
7 //第一個operator <<操作,這里是處理Info的
8 ostream& operator << (ostream& Out, const Info& Obj){
9 Out<<"NAME:"<<Obj.Value<<endl;
10 return Out;
11 }
12 }
然后在外面使用了map來對Info數據進行存儲,那么我們會再定義一個operator<<用來處理map的內容:
1 using namespace TEST_NS;
2
3 //第二個operator <<操作,這里是處理pair<const unsigned int, Info>的
4 ostream& operator<<(ostream& Out, const pair<const unsigned int, Info>& Obj){
5 Out<<Obj.second<<endl;
6 return Out;
7 }
8
然后我們的main函數就這樣子處理:
1 int main()
2 {
3 map<unsigned int, Info> MyData;
4
5 for(unsigned int i = 1; i<10; ++i ){
6 Info info;
7 info.Value = i;
8 MyData.insert( map<unsigned int, Info>::value_type( i, info ) );
9 }
10
11 copy( MyData.begin(), MyData.end(), ostream_iterator< pair<const unsigned int, Info> >(cout, ",") );
12 }
13
上面的代碼看起來一點問題都沒有,但是會依然導致出錯。原因在于編譯器找不到Info的operator <<函數。解決方法為,把第二個operator <<放到第一個operator <<相同的名字空間里去。