我正在阅读一篇关于Overloading the Stream Insertion Operator (<<)的文章。它强调应该返回输出流对象以确保操作符正确级联。但似乎没有回报,输出仍然是正确的,这里有什么不对?
#include<iostream>
class Rational
{
friend std::ostream& operator<<(std::ostream&, const Rational&);
private:
int numerator;
int denominator;
public:
Rational(int num, int den): numerator{num}, denominator{den} {}
};
std::ostream& operator<<(std::ostream& lhs, const Rational& rhs)
{
lhs << rhs.numerator << "/" << rhs.denominator;
//return lhs;
}
int main()
{
Rational r1(3, 5);
std::cout << "The value of r1 is " << r1 << std::endl; // After commenting return lhs; still works fine
}
答案 0 :(得分:2)
这是UB,对于一个应该返回一个对象而没有return语句的函数。它可能运作良好,但没有任何保证。
从标准$6.6.3/2 The return statement [stmt.return]:
开始(强调我的)
在构造函数,析构函数或具有cv
void
返回类型的函数的末尾流动,相当于没有操作数的return
。否则,从main
(basic.start.main以外的函数的末尾流出会导致未定义的行为。
您可能希望查看clang的结果;发出警告
警告:控制到达非空函数的末尾[-Wreturn-type]
并导致无限递归。
答案 1 :(得分:0)
实际上该函数具有未定义的行为。它的工作原理可能是因为它在寄存器(例如EAX)中存储了对流的引用,并且编译器使用该寄存器来传递返回值。