您的位置:首页 > 运维架构

使用copy算法输出map中的内容

2011-12-25 16:35 239 查看
   在C++中,我们常用STL中的copy算法输出序列容器中的元素到输出流。例如我们有一个vector<int>容器,现在我们要将它的内容输出到cout。根据效率考虑,我们不应该使用loop语句实现。我们可以使用copy算法,用习惯i啊棉的语句:

copy(vec.begin(),vec.end().ostream_iterator<int>(cout," "));
这样就可以使用非常简洁的一行代码实现我们的意图。但是如果我们现在想要输出的容器是关联容器呢,比如说map,如果直接将上面代码中的vector<int>换成map<string,int>的话,是不能实现我们的要求的。因为在copy函数中,会调用操作符<<函数,在pair结构的定义中,没有定义对这个操作符的重载。因此需要我们自己实现。

     最初我实现的代码如下所示

 template<typename S, typename T>
 ostream& operator<<(ostream& os, const pair<S,T>& p)
 {
    os << p.first << " " << p.second;
    return os;
 }

int main()
{
    map<string, int> stringIntMap;
    stringIntMap.insert(make_pair("hello",1));
    stringIntMap.insert(make_pair("world",2));
    stringIntMap.insert(make_pair("2011",3));

    for (map<string,int>::iterator it = stringIntMap.begin();it != stringIntMap.end();it++)
        cout << it->first << " " << it->second << endl;

    cout << "post: \n";

    copy(stringIntMap.begin(),stringIntMap.end(),ostream_iterator< pair<string,int> >(cout,"\n"));
    return 0;
}
但是上面的代码无法编译通过,应为在调用copy函数时,copy函数会调用pair对应的<<操作符。pair定义在std命名空间中,但是在std中,没有对pair对应的《进行重载。所以无法编译通过。

一种改进方法就是把新定义的模版函数添加到std命名空间中,即将模版函数定义修改为:

namespace std
{
template<typename S, typename T>
ostream& operator<<(ostream& os, const pair<S,T>& p)
{
os << p.first << " " << p.second;
return os;
}
}
这样就可以编译通过。但是一般来说我们不应该修改std中的内容。另一中改进就是对pair进行封装,代码如下所示:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <cstring>

using namespace std;

template<typename M,typename U>
struct newPair
{
M first;
U second;
newPair():first(M()),second(U()){}

template<typename T1,typename T2>
newPair(const pair<T1,T2>& p):first(p.first),second(p.second){}
};
template<typename M,typename U>
ostream& operator<<(ostream& os, const newPair<M,U>& p)
{
os << p.first << " " << p.second;
return os;
}

int main()
{
map<string, int> stringIntMap;
stringIntMap.insert(make_pair("hello",1));
stringIntMap.insert(make_pair("world",2));
stringIntMap.insert(make_pair("2011",3));

for (map<string,int>::iterator it = stringIntMap.begin();it != stringIntMap.end();it++)
cout << it->first << " " << it->second << endl;

cout << "post: \n";

copy(stringIntMap.begin(),stringIntMap.end(),ostream_iterator< newPair<string,int> >(cout,"\n"));
return 0;
}
这样编译器就会在newPair定义所在的文件查找对<<操作符的重载。

这样也就实现了我们的意图。当然其实我觉得不一定有必要这样操作,使用一个循环就可以了,但是从这个例子中我们知道编译器查找相关的函数时,只在定义相关类的文件中查找

当然我们还可以使用for_each函数实现,但是这个函数明显没有copy直观。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐