operator<<重载需const参数编译:后置++输出报错原因解析
问题:后置递增配合ostream重载时的编译错误原因解析
编译下述重载std::ostream的operator<<代码时,执行后置递增的控制台输出语句会触发编译错误,错误信息如下:
error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream
'} and 'Digit')
已知将operator<<的第二个参数改为const Digit&即可解决该错误,以下是原因解析:
相关代码
class Digit { private: int m_digit; public: Digit(int digit=0) : m_digit{digit} { } Digit& operator++(); // 前置递增无参数 Digit operator++(int); // 后置递增带int参数 friend std::ostream& operator<< (std::ostream& out, /*const*/ Digit& d); }; // 无参数:前置operator++ Digit& Digit::operator++() { // 数字为9时循环到0,否则自增 if (m_digit == 9) m_digit = 0; else ++m_digit; return *this; } // int参数:后置operator++ Digit Digit::operator++(int) { // 创建临时对象保存当前值 Digit temp{*this}; // 调用前置递增修改当前对象 ++(*this); // 返回保存的旧值(临时对象) return temp; } std::ostream& operator<< (std::ostream& out, /*const*/ Digit& d) // 取消const注释即可正常编译 { out << d.m_digit; return out; } int main() { Digit digit(5); std::cout << digit; std::cout << ++digit; // 调用Digit::operator++(); std::cout << digit++; // 调用Digit::operator++(int); // 此行编译失败 std::cout << digit; return 0; }
错误原因解析
核心逻辑是C++不允许临时对象绑定到非const左值引用:
- 前置递增
++digit返回的是Digit&(左值引用),指向原对象本身,属于可修改的左值,能直接匹配operator<<的Digit&参数,因此编译正常。 - 后置递增
digit++返回的是一个临时Digit对象(代码中返回的temp是局部对象,返回时会生成临时拷贝),临时对象属于右值。根据C++规则,右值无法绑定到非const的左值引用,编译器找不到能接收Digit临时对象的operator<<重载,因此抛出"无匹配运算符"的错误。 - 当把
operator<<的参数改为const Digit&时,const左值引用允许绑定到右值(包括临时对象),此时operator<<可以接收后置递增返回的临时对象,编译即可通过。
内容的提问来源于stack exchange,提问作者GoonerZaid
相关产品推荐
相关产品推荐

