2012-04-20 3 views
0
나는 경우,

그것은 상대 반복자

class MyContainer; 

template <typename T> class myiterator :public iterator<bidirectional_iterator_tag, T> 
{ 
    friend class MyContainer; 
    private: 
    T *pointer; 

    myiterator(T *pt):pointer(pt) {} 

    public: 
    T& operator*() {return (*pointer);} 

    const myiterator<T>& operator++() 
    { 
     pointer->current_iterator++; 
     return *this; 
    } 

    bool isEnd(void) const 
    { 
     return pointer->current_iterator == pointer->data.end(); 
    } 
    }; 

class MyContainer 
{ 
    friend class myiterator<MyContainer>; 
    public: 
    typedef myiterator<MyContainer> iterator; 
    typedef myiterator<MyContainer const> const_iterator; 

    private: 
    map<int, int> data; 
    map<int, int>::const_iterator current_iterator; 

    public: 
    MyContainer() {current_iterator = data.begin(); } 

    void addDataPair(int key, int value) {data[key] = value;} 

    int first() const {return (*current_iterator).first;} 
    int second() const {return (*current_iterator).second;} 

    iterator begin() 
    { 
     current_iterator = data.begin(); 
     return iterator(this); 
    } 

    const_iterator begin() const 
    { 
     return const_iterator(this); 
    } 
    }; 

이 코드 실행 확인 요소의 작업에 더 유연한 제어를 제공 할 수 있도록 내가 자기 정의 된 컨테이너와 STL 컨테이너를 확장하고

의에서 const_iterator를 정의하는 데 실패 다음과 같이 iterator를 사용한다.

MyContainer h; 

h.addDataPair(1, 1); 
h.addDataPair(2, 2); 
h.addDataPair(3, 3); 

for (MyContainer::iterator it=h.begin(); !it.isEnd(); ++it) 
{ 
    cout << (*it).first() << " " << (*it).second() << endl; 
} 

그러나 iterator를 const_iterator로 변경하면 컴파일되지 않는다. 나는 반복적 인 반복자를 정의하기 위해 X에서 X const로 value_type을 대체한다고 언급 한 기사를 읽었습니다. 이것이 제가 코드에서했던 것입니다. 하지만 필자는 필자의 경우 반복기에서 반환 된 참조가 컨테이너 자체이기 때문에 곧 내 경우에는 작동하지 않을 수도 있음을 알게되었습니다. 나는 코딩을 복제하지 않고 const_iterator를 만드는 방법을 모른다.

또한 iterator는 std :: iterator에서 파생되었지만 내 반복자의 생성자를 무시할 수 없다는 것을 알았습니다. T * pt 외에도 반복자에 하나 이상의 매개 변수를 전달할 수있는 방법이 있습니까? 감사.

+0

조금 이상합니다. MyContainer는 컨테이너와 반복자 인 것처럼 보입니다. –

+0

내가 아는 :) 나는지도를 수정하는 코드를 원하지 않기 때문에 의 요소가 직접적으로 래퍼를 써서 연산자 [], 연산자 ++ 등으로지도 데이터에 액세스하려고하는 동안 제어 할 수있다. std :: map을 상속하려고하지만 가상 소멸자 때문에 그렇게하지 않는 것이 좋습니다. 어쨌든 이것은 인터페이스를지도만큼 가까이두고 컨트롤을 추가 할 수있는 유일한 방법입니다. – user1285419

+0

const 맵에서 제공하지 않을 내용을 원하십니까? –

답변

1

첫 번째 문제 :

당신은 변경하면이 :

for (MyContainer::iterator it=h.begin(); !it.isEnd(); ++it) 

당신이 begin()end()에서 const가 아닌 iterator을 얻을하고 const_iterator에서 초기화하려고 다음

for (MyContainer::const_iterator it=h.begin(); !it.isEnd(); ++it) 

에 하지만 그 유형이 다르며 my_iterator 템플릿에 허용되는 생성자가 없습니다. 다른 유형의 건설. 하는 const_iterator

template<typename> friend class myiterator; 

template<typename T2> 
    myiterator(myiterator<T2> const& i) : pointer(i.pointer) { } 

당신은 또한 operator*을 const해야

을하지만 더 큰 문제는 여전히있다 (그것이 역 참조에 반복자를 변경하지 않습니다.) :

당신은 추가하여이 문제를 해결할 수 있습니다 const MyContainer을 가리키고 있지만 const_iterator::operator++은 해당 객체를 변경해야합니다.이 객체는 const이므로 변경할 수 없습니다. 따라서 당신은 당신의 const_iterator을 증가시킬 수 없습니다. 즉, 그것을 반복 할 수 없습니다! 당신은 그 디자인을 다시 생각하고 싶을지도 모른다.