2016-11-09 60 views
1

我正在閱讀有關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 
} 

回答

2

這是UB,因爲一個函數應該返回一個對象,而沒有返回語句。它可能運作良好,但沒有保證。

從標準,$6.6.3/2 The return statement [stmt.return]

(重點煤礦)

流動關閉構造,析構函數,或用CV void返回類型的函數的結束相當於一個return與沒有操作數。否則,關閉除mainbasic.start.main)之外的其他功能的結尾將導致未定義的行爲


您可能希望看到clang結果;其給出警告

警告:控制到達非void函數[-Wreturn型]的端

和結果在一個無限遞歸。

0

事實上該函數有未定義的行爲。它的工作原理可能是因爲它在寄存器(例如EAX)中存儲對流的引用,並且該寄存器被編譯器用來傳遞返回值。