2017-07-03 16 views
2

讓說我定義某種容器A的:`const_iterator`確實需要與`iterator`不同的類嗎?

struct A 
{ 
    iterator begin(){ return iterator(this,0); } 
    const iterator cbegin() const { return iterator(this, last());} 
    //... 
}; 

假設現在我要宣佈iterator(A部分):

struct A::iterator 
{ 
    iterator (A* ptr, size_t idx){}; 
    //... 
}; 

其中我會用這樣的:

const A a; 
A::iterator it = a.cbegin(); 

這不起作用,因爲傳遞給iterator構造函數的指針是非常量的。

理想的解決方案是類似的東西返回一個const對象的特定構造:

const A::iterator(const StringUtfInterface *p, size_t s); //Not valid 

這是(明顯)無效在C++中。我想知道這個問題的解決方法是什麼?

我真的需要聲明/定義一個新的const_iterator類嗎? const關鍵字不夠?


相關問題(但不相同):

+0

迭代器,const迭代器和const_iterator之間的區別與常規指針('T *'),const指針('T * const')和指向const('const * ')。你需要所有三種。 –

回答

1

什麼只是超載iterator構造以支持不斷容器嗎?

struct A::iterator { 
    iterator(A* ptr, size_t idx) {} 
    iterator(const A* ptr, size_t idx) {} 
    //... 
}; 

這樣就沒有必要定義兩個單獨的類,並且您將始終根據容器的常量獲取(隱式)正確的迭代器。

UPDATE

如下評論,你可以使用一個模板,如(未全面實施)

struct A { 
    template<class T> 
    struct base_iterator { 
    private: 
    T* _ptr; 

    public: 
    base_iterator(T* ptr, size_t idx) : _ptr(ptr) {} 

    T operator*() { return *_ptr; } 
    //... 
    }; 

    typedef base_iterator<A> iterator; 
    typedef base_iterator<const A> const_iterator; 

    iterator begin() { return iterator(this, 0); } 
    const_iterator cbegin() const { return const_iterator(this, 0); } 
    //... 
}; 
+2

你會從'operator *'返回什麼類型? –

+0

哦!我明白了......現在很明顯,我沒有實現太多的迭代器,不是嗎? ;) – cbuchart

+0

使用'base_iterator'模板可能會有效,但請記住,您需要從'base_iterator '構建'base_iterator '。 –

3

const關鍵字是不夠的?

其實,const關鍵詞太多:它迫使你寫

const A::iterator it = a.cbegin(); 

防止您以後使用++it

您需要提供兩個獨立的類,但這並不意味着您必須編寫兩次代碼。您可以通過這樣一種方式來構建迭代器的實現,即將完成所有工作的公共類嵌入常量和非常量迭代器實現中,這些實現將嵌入式實現的相關方法公開給調用方。

+0

你是否推薦從iterator擴展const_iterator,const_iterator的iterator或者const/non-const類型的模板? –

+0

@AdrianMaire我不會從'const_iterator'擴展非const'iterator',因爲它們提供了相同的成員函數和運算符,返回不同類型的對象。使用模板可能會起作用,但我認爲將一個通用實現封裝到兩個單獨的類中會更困難,或者如果您願意的話,甚至可以私自從一個通用基類繼承。 – dasblinkenlight

相關問題