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

2 篇文章 0 订阅
对于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 <<相同的名字空间里去。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值