2017-11-25 114 views
0

我創建了一個僞容器類(它不包含任何元素)和一個此容器的迭代器類。 下面的代碼總是輸出「776」我的系統上(我的編譯器是gcc 5.4.0)std :: reverse_iterator奇怪的行爲(UB?)

#include <iostream> 
#include <iterator> 

class Container 
{ 
public: 
    class Iterator; 
    Container()=default; 
    Container::Iterator begin(); 
    Container::Iterator end(); 
}; 

class Container::Iterator: public std::iterator<std::bidirectional_iterator_tag, size_t> 
{ 
public: 

    Iterator(size_t n); 
    size_t& operator*(); 
    Container::Iterator& operator--(); 
    const Container::Iterator operator--(int); 

    bool operator==(const Container::Iterator& rhs) const; 
    bool operator!=(const Container::Iterator& rhs) const; 
    private: 
    size_t n_; 
}; 



Container::Iterator Container::end() 
{ 
    return Iterator(777); 
} 





Container::Iterator::Iterator(size_t n): 
    n_(n) 
{ 
} 

size_t& Container::Iterator::operator *() 
{ 
    return n_; 
} 

Container::Iterator& Container::Iterator::operator--() 
{ 
    n_--; 
    return *this; 
} 

const Container::Iterator Container::Iterator::operator--(int) 
{ 
    Container::Iterator oldVal = *this; 
    n_--; 
    return oldVal; 
} 

int main() 
{ 
Container cont; 
std::reverse_iterator<Container::Iterator>revit(cont.end()); 
//as cppreference says, "For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i-1) is always true...", so I expect that the output must be the same as if I used instead next commented line, and it does so on my system 
    // auto it = cont.end(); it--; std::cout << *it << std::endl; 
    std::cout << *revit << std::endl; 
return 0; 
} 

但是當我使用任何在線編譯器(用C++ 11的支持),該代碼輸出只是「0 '(除了一個Clang版本,那麼輸出是一些'隨機'大數字)

我弄不明白,我的錯誤在哪裏?

回答

1

std::reverse_iterator::operator*is equivalent to

Iterator tmp = current; return *--tmp; 

(其中current是通過reverse_iterator此實例包裹底層迭代器)。

*tmp返回對tmp的成員的引用 - 它超出了範圍,並在std::reverse_iterator::operator*返回時帶出該成員。因此,*revit返回一個懸掛參考;隨後的嘗試使用它展示未定義的行爲。