2011-09-26 5 views
57

STL 컨테이너 대신 사용되는 컨테이너에 대한 반복기를 작성하고 있습니다. 현재 STL 컨테이너는 c++11 foreach syntax과 같이 여러 장소에서 사용되고 있습니다 (예 : for(auto &x: C)). 코드는 다음에 호출 할 수 있도록 내가 사용자 지정 컨테이너에 대한 올바른 반복자를 사용하는 자동차를받을 수 있나요 어떻게C++ 11 foreach 구문 및 사용자 지정 반복기

template< typename Type> 
class SomeSortedContainer{ 
    std::vector<typename Type> m_data; //we wish to iterate over this 
    //container implementation code 
};  
class SomeSortedContainerIterator{ 
    //iterator code 
}; 

: 우리는 STL 컨테이너를 래핑하는 사용자 정의 클래스를 사용하는 코드를 업데이트 할 필요가있다 way :?

SomeSortedContainer C; 
for(auto &x : C){ 
    //do something with x... 
} 

일반적으로 자동으로 클래스에 올바른 반복자를 사용하려면 무엇이 필요합니까?

+0

Visual Studio를 사용하는 경우 변수 이름 위로 마우스를 가져 가면 해당 형식을 볼 수 있습니다. IIRC에서는 '자동'이 아닌 실제 유형을 보여줍니다. –

답변

50

당신은 두 가지 선택이 있습니다 C.begin()C.end()처럼 호출 할 수 beginend 이름

  • 당신이 제공하는 멤버 함수를;
  • 그렇지 않으면, 당신은 begin 및 인수 종속적 조회를 사용하여 발견, 또는 네임 스페이스 std에서 할 수 end라는 이름의 무료 기능을 제공하고, begin(C)end(C)처럼 호출 할 수 있습니다. 다른 사람이 언급 한 것처럼
+2

[ "Range-for"진술]에 대한 자세한 설명은 Stroustrup의 [C++ 11 FAQ] (http://www.stroustrup.com/C++11FAQ.html)를 참조하십시오 (http : //www.stroustrup .com/C++ 11FAQ.html # for) (회원/기능 우선 순위 포함). – rluba

50

범위 기반을 사용하려면 수업에 const_iterator begin() constconst_iterator end() const 명의 회원이 있어야합니다. 또한 세계 begin 함수에 과부하가 걸릴 수 있지만 멤버 함수가 있으면 내 의견이 더 좋습니다. iterator begin()const_iterator cbegin() const도 권장되지만 필수는 아닙니다. 당신은 단순히 하나의 내부 용기를 반복하고 싶다면, 그건 정말 쉬운 : 사용자 정의하지만 아무것도 반복하려는 경우, 당신은 아마 당신의 용기 내부 클래스로 자신의 반복자를 설계해야합니다

template< typename Type> 
class SomeSortedContainer{ 

    std::vector<Type> m_data; //we wish to iterate over this 
    //container implementation code 
public: 
    typedef typename std::vector<Type>::iterator iterator; 
    typedef typename std::vector<Type>::const_iterator const_iterator; 

    iterator begin() {return m_data.begin();} 
    const_iterator begin() const {return m_data.begin();} 
    const_iterator cbegin() const {return m_data.cbegin();} 
    iterator end() {return m_data.end();} 
    const_iterator end() const {return m_data.end();} 
    const_iterator cend() const {return m_data.cend();} 
};  

.

class const_iterator : public std::iterator<random_access_iterator_tag, Type>{ 
    typename std::vector<Type>::iterator m_data; 
    const_iterator(typename std::vector<Type>::iterator data) :m_data(data) {} 
public: 
    const_iterator() :m_data() {} 
    const_iterator(const const_iterator& rhs) :m_data(rhs.m_data) {} 
    //const iterator implementation code 
}; 

반복자 클래스를 작성하는 방법에 대한 자세한 내용은 my answer here를 참조하십시오.

2

SomeSortedContainerbegin()end()을 제공하면됩니다. 그리고 이것들은 당신의 경우 SomeSortedContainerIterator에 표준 호환 순방향 반복자를 반환해야합니다. 실제로는 std::vector<Type>::iterator을 감쌀 것입니다. 표준을 준수한다는 것은 일반적인 증가 및 역 참조 연산자뿐만 아니라 value_type, reference_type, ... typedefs를 제공해야 함을 의미하며 foreach 구문에서 컨테이너 요소의 기본 유형을 결정하는 데 사용됩니다. 하지만 std::vector<Type>::iterator에서 전달할 수 있습니다.

+3

'begin'과'end' 멤버 함수가 없다면 foreach는'begin'과'end' 비 멤버 함수를 사용할 수도 있습니다. –

+0

@Mike 컨테이너를 단일 매개 변수로 사용하는 자유 함수를 의미합니까? 나도 몰랐어. 기존 컨테이너 클래스를 확장하는 데 유용합니다. –

6

, 컨테이너는 begin()end() 기능을 구현 (또는 매개 변수로 컨테이너의 인스턴스을 전역 또는 std:: 기능을 가지고)해야합니다.

해당 함수는 동일한 유형 (일반적으로 container::iterator이지만 그 규칙 만 사용)을 반환해야합니다. 반환되는 형식은 operator*, operator++operator!=을 구현해야합니다.