C++重载operator>>报错:无法绑定std::istream左值到std::basic_istream<char>&&
fraction类operator>>重载报错问题分析
你的fraction类代码如下:
class fraction { // type definition int num; int denom; ostringstream sstr; public: fraction(int c=0, int d=1) : num(c), denom(d) { sstr = ostringstream(); } fraction(const fraction &f) : num(f.num), denom(f.denom) { /*void*/ } friend ostream& operator<<(ostream &os, const fraction &f){ os << "(" << f.num << "/" << f.denom << ")"; return os; } friend istream& operator>>(istream &is, const fraction &f){ is >> "(" >> f.num >> "/" >> f.denom >> ")"; // Exception thrown on this line on "is >>" return is; } };
重载operator<<正常工作,但operator>>抛出错误:
cannot bind 'std::istream {aka std::basic_istream
}' lvalue to 'std::basic_istream &&'
错误原因及修正
1. 第二个参数不能是const引用
operator>>的作用是从输入流读取数据并修改fraction对象的成员,但你把第二个参数声明为const fraction &f——const对象的成员无法被修改,这不仅逻辑矛盾,也是导致编译错误的直接原因之一。
修正:去掉const,改为非const引用:
friend istream& operator>>(istream &is, fraction &f)
2. 错误的输入匹配方式
is >> "("这种写法是无效的,istream的operator>>不支持直接匹配字符串字面量。要解析(num/denom)格式的输入,你需要手动读取并检查分隔符:
修正后的operator>>实现:
friend istream& operator>>(istream &is, fraction &f){ char left_paren, slash, right_paren; // 按格式读取字符和数值 is >> left_paren >> f.num >> slash >> f.denom >> right_paren; // 检查输入格式是否符合预期 if (left_paren != '(' || slash != '/' || right_paren != ')') { is.setstate(ios::failbit); // 格式错误时设置流失败状态 } // 检查分母不能为0 if (f.denom == 0) { is.setstate(ios::failbit); } return is; }
其他需要注意的问题
- 拷贝构造函数未处理
sstr成员:当前拷贝构造函数只复制了num和denom,sstr会被默认初始化,若需要拷贝sstr的状态,应该在初始化列表中添加sstr(f.sstr)。 - 构造函数可优化:构造函数中
sstr = ostringstream();可以改为初始化列表初始化:fraction(int c=0, int d=1) : num(c), denom(d), sstr() {}。 - 分母合法性检查:构造函数中应该添加分母不为0的检查,避免创建无效的分数对象。
内容的提问来源于stack exchange,提问作者Marc Miller
相关产品推荐
相关产品推荐

