Sun C++ 5.12下ostream_withassign<<运算符编译错误原因咨询
问题分析与解决方案
你的问题根源出在运算符重载的参数类型和key()返回值的常量性不匹配上,咱们一步步拆解清楚:
关键细节梳理
- 你的
DictIterator::key()是const成员函数,返回的是**const Key类型的临时值**(函数签名K key() const;里的K对应Key,按值返回的对象本身是临时右值,且因为成员函数是const,返回值也具备常量属性) - 你重载的
<<运算符签名是:ostream& operator<<(ostream &, Key&);—— 第二个参数是非const的左值引用
直接输出报错的原因
在你使用的C98/03标准下(因为你明确说无C0x特性),非const的左值引用不能绑定到临时对象或者const对象。当你直接写cout << iterator.key();时,iterator.key()返回的是一个临时的const Key实例,而你的operator<<要求的是可修改的Key&,编译器找不到匹配的重载,因此抛出"The operation ostream_withassign<<Key is illegal"的错误。
赋值变量后正常的原因
当你写Key key(iterator.key());时,你创建了一个非const的左值变量key,这个变量可以被正常绑定到Key&引用,所以cout << key;能匹配到你的重载运算符,自然编译通过。
修复方案
推荐方案:修改运算符重载为const引用
输出操作本身不应该修改被输出的对象,所以把<<运算符的第二个参数改成const Key&是最规范的做法:
ostream& operator<<(ostream &os, const Key& key);
修改后,临时对象、const对象、普通左值都能正常绑定到const Key&,直接写cout << iterator.key();就可以正常编译运行。
折中方案(无法修改重载时)
如果因为是遗留代码不能修改运算符签名,你目前用临时变量中转的写法就是可行的折中方式。或者也可以用const_cast强制转换(不推荐,存在潜在风险):
cout << const_cast<Key&>(iterator.key());
内容的提问来源于stack exchange,提问作者John3136
相关产品推荐
相关产品推荐

