C++中使用copy和ostream_iterator来输出map的内容

本文探讨了在C++中如何有效地输出map容器的内容,并解决了使用copy和iterator时出现的编译错误问题。通过自定义类型和使用transform函数提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于copy配合iterator来输出一些容器的便利性是非常喜欢的,但是copy在处理map容器的时候,很容易导致编译出错,问题代码如下:
 1 ostream& operator << (ostream& outconst pair<const int,int>& value)
 2 {
 3     out<<"("<<value.first<<","<<value.second<<")";
 4     return out;
 5 }
 6 int main()
 7 {
 8     map<intint> 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 intint> >(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& outconst 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& outconst string& str)
 2 {
 3     return out<<str;
 4 }
 5 
 6 string toString(const pair<const intint>& value)
 7 {
 8     ostringstream ost;
 9     ost<<"("<<value.first<<","<<value.second<<")";
10     return ost.str();
11 }
12 
13 int main()
14 {
15     map<intint> 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 <<相同的名字空间里去。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值