2013-05-10 34 views
1

我目前正在嘗試編寫一個樹型數據結構。在我嘗試爲我的原始數據結構創建一個迭代器,然後瞭解STL規範後,我領導了這條路。如何分配這種明顯的錯誤類型不會導致編譯器錯誤?

我會嘗試濃縮一下我的代碼,並且仍然顯示讓我感到困惑的代碼沒有編譯。如果缺少某些東西,我會很樂意在後面添加它。

// Relevant bits of tree.hpp 
template <class T, class Alloc = std::allocator<T> > 
class tree 
{ 
public: 
    struct NODE 
    { 
     T     data; 
     std::vector<NODE*> children; 
     NODE*    parent; 
     NODE*    right; 

     // Not shown here: size() 
    }; 

    typedef Alloc       allocator_type; 
    typedef typename Alloc::value_type  value_type; 
    typedef value_type&      reference; 
    typedef const value_type&    const_reference; 
    typedef typename Alloc::difference_type difference_type; 
    typedef typename Alloc::size_type  size_type; 

    class iterator 
    { 
    public: 
     typedef typename Alloc::difference_type difference_type; 
     typedef typename Alloc::value_type  value_type; 
     typedef typename Alloc::reference  reference; 
     typedef typename Alloc::pointer   pointer; 
     typedef std::forward_iterator_tag  iterator_category; 

     iterator(NODE* node) : currentNode_(node) {} 
     iterator(const iterator& i) : currentNode_(i.currentNode_) {} 

     iterator& operator++(); 

     // Not shown here: operator==, operator!=, operator*, operator-> 

    private: 
     NODE* currentNode_; 
    }; 

    // Not shown here: constructors, begin(), end(), size(), empty(), etc... 

private: 
    NODE root_; 
}; 

// Relevant bits of tree.cpp 
template <class T, class Alloc> 
typename tree<T, Alloc>::iterator& 
tree<T, Alloc>::iterator::operator++() 
{ 
    if (!currentNode_->children.empty()) 
     currentNode_ = currentNode_->children.front(); 

    else if (currentNode_->right != nullptr) 
     currentNode_ = currentNode_->right; 

    else { 
     while (currentNode_->parent->right == nullptr) 
      currentNode_ = currentNode_->parent; 
     currentNode_ = currentNode_->parent->right; 
    } 
    currentNode_ = "abc - Just some random string, definitely not a NODE*"; 
    return *this; 
} 

爲什麼我可以將看似任何隨機的事情currentNode_?而且,即使我返回的東西顯然不是iterator&,或者甚至只是將返回語句放在一起,代碼仍然很愉快地編譯。到底是怎麼回事?

我還沒有測試過在實際調用代碼時會發生什麼,因爲我還沒有實現實際的代碼來填充樹。我希望確保在繼續這些之前獲得這些基礎知識。

忍者編輯:爲了編譯,我打電話find src/ -name "*.cpp" | xargs g++ -Isrc/ -O3 -Wall -Wextra -pedantic -std=gnu++0x || exit 1

+2

帶模板的事情是它不是一個錯誤,除非你實例化它。所以只要你不嘗試使用'樹 :: iterator :: operator ++',代碼就會被編譯。嘗試使用它,看看會發生什麼。或者甚至嘗試聲明一棵樹(*我認爲錯誤應該顯示*) – stardust 2013-05-10 22:58:44

回答

2

由於currentNode_取決於模板的類型,因此只有在您實際實例化/使用函數之前,纔會完成該部分編譯。一旦你調用你的操作符,你會在文字串分配上得到預期的編譯錯誤。