今天在写一个文件输入路径的时候,需要将一个目录下的所有文件在屏幕上显示一下,并且有一个唯一的标识;于是我自然就想到了用map容器,当我把代码
像下面这样写好的时候;
#include <iostream>
#include <iterator>
#include <map>
int main()
{
std::map<int, std::string> _mmap;
for (auto i = 0; i < 10; i++) {
_mmap.insert(std::make_pair(i, "hellow"));
}
std::copy(_mmap.begin(), _mmap.end(), std::ostream_iterator < std::map<int, std::string>::value_type>(std::cout, "\n"));
return 0;
}
编译发现报错,心想应该是没有找到<<运算符重载。于是自己写一个重载,改成了这样
#include <iostream>
#include <iterator>
#include <map>
std::ostream & operator<<(std::ostream & out, std::pair<int, std::string> & value)
{
return out << value.first << " " << value.second.c_str();
}
int main()
{
std::map<int, std::string> _mmap;
for (auto i = 0; i < 10; i++) {
_mmap.insert(std::make_pair(i, "hellow"));
}
std::copy(_mmap.begin(), _mmap.end(), std::ostream_iterator < std::map<int, std::string>::value_type>(std::cout, "\n"));
return 0;
}
本以为这次应该对了,发现程序也编译都通不过,最后经过一番百度在网上找到了答案;这里先要感谢这位博友,
链接在此。
这是因为std::cout在输出时找不到std::map<int,std::string>::value_type(其实就是std::pair<int,std::string>)在std空间的<<运算符重载,为什么是在std空间呢;上面的链接已经说得很清楚了。std::cout输出的类型为std::pair<int,std::string>那么编译器就会去找std::pair<int,std::string>的<<运算符重载,由于其中的数据类型是标准的数据类型int和std空间的数据类型string,所以只会在std空间去查找。所以要想正确编译我们应该将其中的一个数据类型改为自定义类型,或者在std空间写出std::pair<int,std::string>的<<运算符重载。所以我将重载部分改成了这样
namespace std {
ostream & operator<<(ostream & out, pair<int, string> & value)
{
return out << value.first << " " << value.second.c_str();
}
}
int main()
{
std::map<int, std::string> _mmap;
for (auto i = 0; i < 10; i++) {
_mmap.insert(std::make_pair(i, "hellow"));
}
std::copy(_mmap.begin(), _mmap.end(), std::ostream_iterator < std::map<int, std::string>::value_type>(std::cout, "\n"));
return 0;
}
改成这样之后按理说应该对了吧,最终发现还是编译不通过;再次经过漫长的百度终 在这里找到了答案,我们写的<<运算符的第二个参数要求输入一个pair<int,std::string>
&的参数,而我们在使用std::cout像这样输出结果std::cout << pair 1+pair2,这里实际是输出后两者运算之后的临时对象。而对于该类型的<<运算符要求输入pair<int,std::string>&类型,但是引用是不能指向临时对象的;所以这里加一个const就可以了,const引用可以指向临时对象。当然我这里并不是输出+运算符计算的临时对象,但应该原因就是这个了,很可能是返回的value.first << " " << value.second.c_str()也是一个临时对象,所以要加const。最后贴一个正确的代码。当然也有可能std空间的<<运算重载就明确规定该参数必须带const,反正原因找到就对了。
#include <iostream>
#include <iterator>
#include <map>
namespace std {
ostream & operator<<(ostream & out, const pair<int, string> & value)
{
return out << value.first << " " << value.second.c_str();
}
}
int main()
{
std::map<int, std::string> _mmap;
for (auto i = 0; i < 10; i++) {
_mmap.insert(std::make_pair(i, "hellow"));
}
std::copy(_mmap.begin(), _mmap.end(), std::ostream_iterator < std::map<int, std::string>::value_type>(std::cout, "\n"));
::getchar();
return 0;
}