对于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 <<相同的名字空间里去。