2014-10-10 2 views
0

내 자신의 사용자 지정 벡터 클래스의 일부로 역 반복자를 쓰고 있습니다. 지금까지 내가 쓴 것은 다음과 같다.STL 컨테이너 반복자와 C 포인터 반복자의 차이점

class MyVector 
{ 
    public: 

    typedef T       value_type; 
    typedef value_type*     pointer; 
    typedef const value_type*   const_pointer; 
    typedef value_type&     reference; 
    typedef const value_type&   const_reference; 
    typedef pointer      iterator; 
    typedef const_pointer    const_iterator; 
    typedef size_t      size_type; 

    class reverse_iterator 
    { 
     private: 

     iterator iter; 

     public: 

     inline reverse_iterator(iterator a=0) : iter(a) {} 
     inline reverse_iterator(const reverse_iterator& rev_iter) : iter(rev_iter.iter) {} 
     inline reverse_iterator& operator++() 
     { 
      --iter; 
      return *this; 
     } 
     // and remaining other operator functions 
    }; 

    inline iterator begin (void) { return ((iterator)data_array);   } 
    inline iterator end (void) { return ((iterator)data_array+number_of_elements); } 
    inline reverse_iterator  rbegin(void) { return end()-1;} 
    inline reverse_iterator  rend(void)  { return begin()-1;} 


    //functions for myvector class 
}; //end of Myvector class 

위의 클래스 iterater는 C 스타일 포인터이고 reverse_iterator는 클래스입니다. 내가

main() 
    { 
     myVector<int> i; 
     myVector<int>::reverse_iterator rit= i.begin(); 
    } 

을 수행 할 때 그래서 내 reverse_iterator는() 기능을 시작하고 코드를 컴파일하고 실행 로 초기화된다. 그러나 STL의 iterator와 reverse_iterator의 경우에는 발생하지 않습니다. 이러한 초기화 작업을 방지합니다. 예 : reverse_iterator가 begin() 함수로 초기화되지 않도록하려면 rbegin()으로 초기화해야합니다.

그런 초기화를 피하려면 어떻게해야합니까? STL에있는 것과 같은 다른 반복기를 작성해야합니다. 그리고 나는 그것을 쓸 수 없다고 생각합니다. 제발 좀 해결책을주세요 ...

+0

'iterator'를'reverse_iterator'로 명시 적으로 허용합니다. 왜냐하면 후자는 전자 메일에서 변환 생성자를 제공했기 때문입니다. 해당 생성자를 제거하십시오. – juanchopanza

+1

코드 샘플을 [MCVE] (http://stackoverflow.com/help/mcve)로 줄이면 더 쉬울 것입니다.많은 코드가 문제와 관련이 없지만 컴파일하기에 충분하지 않습니다. – juanchopanza

답변

3

반복자와 반대 반복자는 약간의 차이가 있습니다.

가장 명백한 : 각 반복기를 증가 시키면 반대 방향으로 이동합니다.

덜 명확한 : begin()의 반송은 이 아니며, 역 반복기의 끝이입니다. begin()-1이됩니다. end()은 C++ 범위가 반 개방 즉 [시작, 끝]이므로 "한 끝"을 나타냅니다. 당신이 당신의 역 반복자에 begin()end()를 교환 할 경우 역방향 반복자가 범위 (시작, 끝]을해야합니다. 즉

, STL 컨테이너는 모두 begin()end()rbegin()rend()가, 심지어 왜 이유가있다 반복자와는 반복자를 반대로하면 자신이 어떤면에서 호환 될 수

0

완전히 개인 reverse_iterator의 생성자를 확인 reverse_iteratoriterator (포인터)에서 변환을 방지하고 MyVectorreverse_iterator의 친구 만들려면 :.

class MyVector 
{ 
    // ... 
    class reverse_iterator 
    { 
    private: 
    friend class MyVector; 
    reverse_iterator(iterator a=0) : iter(a) {} 
    // ... 
    }; 
    // ... 
}; 

해당 변환을 사용할 수는 있지만 자동으로 사용하지 않으려면 해당 생성자를 그냥 explicit으로 만드십시오. 관련이없는 노트에서

class MyVector 
{ 
    // ... 
    class reverse_iterator 
    { 
    public: 
    explicit reverse_iterator(iterator a=0) : iter(a) {} 
    // ... 
    }; 
    // ... 
}; 

, 나는 또한 rbegin()의 구현은 아마도 (이 data_array 초기화 코드에 의존하기 때문에 내가 확실히 말할 수 없다) 정의되지 않은 동작을 호출하는주의 사항 : 포인터를 감소 할 수 없습니다 배열의 처음으로

그런데 키워드 inline은 필요하지 않습니다. 클래스 정의 안에 멤버 함수 본문을 작성하면 자동으로 인라인됩니다. 물론 inline도 문제가되지 않습니다.