起因,昨天写的一段小程序
#include
<
iostream
>
#include
<
map
>
#include
<
iterator
>
#include
<
vector
>
#include
<
algorithm
>
using
namespace
std;
ostream
&
operator
<<
(ostream
&
os,
const
pair
<
int
,
int
>
&
mp)
{
os
<<
mp.first;
os
<<
mp.second;
return
os;
}
int
_tmain(
int
argc, _TCHAR
*
argv[])
{
pair
<
int
,
int
>
mmp(
100
,
200
);
cout
<<
mmp;
map
<
int
,
int
>
imap;
map.insert(make_pair(
100
,
100
));
imap.insert(make_pair(
22
,
123
));
copy(imap.begin(),imap.end(),ostream_iterator
<
pair
<
int
,
int
>
>
(cout,
"
\n
"
));
return
0
;
}
未能通过编译,报的错误是:没有找到接受“<未知>”类型的右操作数的运算符(或没有可接受的转换),百思不得其解,应为我觉得
我明明重载了<<运算符。再没有办法的情况下请教了CSDN论坛上的一些朋友,终于弄明白了其中的原因(可能这个知识点很菜,高手
不要见笑)。
ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
{
*_Myostr << _Val;///~~~~~~~~~~~~~~~~~~~~~~~这是在ostream_iterator类源代码当中,就是这里报错了
if (_Mydelim != 0)
*_Myostr << _Mydelim;
return
}
在上面那到程序当中_Val类型是pair<int,int> *_Myostr类型是ostream,显然这里出错,代表编译器就好像没有看到我的重载。出现以上现象的原因就是当编译器看到*_Myostr<<_Val时候,它会先在自己的名字空间查找<<,这个估计发生在模板编译的第一个阶
段(不知道是不是该这么说),它看到了一个范型的<<重载(估计),于是就不在去别的地方查找。可是到了实例化的时候,编译器发现
没有匹配的<<运算,于是就报错了。如果我们把重载写在std空间里,也就是和ostream_iterator一个空间里,编译器在实例化的时
候也会把它纳入考虑对象之一,这个时候它就会选择我们的重载,一切就OK了。注意,如果编译器在*_Myostr<<_Val所在名字空间没有找到
<<重载,则它会进行类型相关查找。就是去定义*_Myostr类型或_Va类型的空间查找,再找不到那它就会去全局空间去查找。
个人理解,不是很肯定,诚请高手纠正,感谢CSDN上周星星和晨星。