2010-02-03 3 views
3

기본적으로 반복기를 지정할 필요없이 컨테이너 클래스의 인스턴스를 탐색하는 데 사용할 수있는 일반 반복기를 반환 할 수있는 기본 컨테이너 클래스가 있어야합니다. 템플릿. 나는 기본 컨테이너를 클래스 템플릿 위에 구현할 수 없다고 생각한다. 그러면 미리 알려지지 않은 템플릿 클래스를 기반으로 한 순회 알고리즘이 필요하다. 기본 컨테이너는 상속 받아 구현할 수 있으며 (사용자 정의 또는 표준) 컨테이너 유형/구현을 사용하여 구현할 수 있습니다. 여기 명확하게 몇 가지 코드 예제입니다 : 다음 컨테이너 개체의 목록을해야합니다내부 컨테이너를 숨기고 기본 컨테이너를 통해 일반 작업을 수행하기 위해 반복자 사용하기

struct MyObject { 
    int myInt; 
} 

// an abstract container 
class BaseContainer { 
public: 
    virtual void insertMyObject(MyObject& obj) = 0; 
    virtual iterator getFirst(); // the iterator type is for demonstration purposes only 
    virtual iterator getLast(); // the iterator type is for demonstration purposes only 
} 

// Sample container class that uses a std::vector instance to manage objects 
class BaseContainer_Vector : public BaseContainer { 
public: 
    void insertMyObject(MyObject& obj); // e.g. just pushes back to the vector 
    iterator getFirst(); // needs to override the iterator? 
    iterator getLast(); // needs to override the iterator? 
private: 
    std::vector<MyObject> objectContainer; 
} 

는, 나는 이상이 컨테이너와 저장된 객체 모두를 반복합니다.

std::vector<MyContainer*> containers; 
for(int i=0 ; i<containers.size() ; i++){ 
    iterator i = containers[i]->getFirst(); 
    iterator iend = containers[i]->getLast(); 
    for(; i != iend ; i++) { 
    std::cout << (*i).myInt << std::endl; 
    } 
} 

부스트 foreach 매크로 문에 대한 지원이 추가로 필요합니다. range_begin과 range_end 함수가 적절히 기능하는 한 확장 기능을 지원합니다. 그러나, boost doc의 예제는 반환 유형으로 std :: string :: iterator를 사용합니다. 반면에 일반적인 iterator 클래스가 필요하며이를 수행하는 방법도 알 수 없습니다.

std::vector<MyContainer*> containers; 
for(int i=0 ; i<containers.size() ; i++){ 
    BOOST_FOREACH(MyObject obj, *(containers[i])) { 
    std::cout << obj.myInt << std::endl; 
    } 
} 

은 내가 내 자신의 반복자 클래스, BaseContainer 그 기본 반복자를 확장 자신의 반복자를 정의해야합니다 확장 각 클래스를 정의 할 수 있다고 생각합니다. 그러나 필자는 표준 iterator (stl 또는 boost)를 사용하여이 구조를 지원하는 대신 내 자신의 반복자를 작성하는 것을 선호합니다. 나는이 접근법이 효과가있을 것이라고 생각하지만, 효율성에 대한 논평은 열려 있습니다.

이 문제를 우아하게 해결할 수있는 방법이 있습니까? 아니면 고통없이이 문제를 해결할 수있는 간단한 요점을 놓치고 있습니까?

비슷한 질문은 here이지만 제안 된 솔루션은 내 필요에 따라 약간 복잡해 보입니다. 요구 사항은 내가 이해할 수있는 한 많이 다릅니다.

+1

실제 사용 사례는 무엇입니까?컨테이너의 동적으로 선택된 두 개의 버전이 필요합니까? 아니면 컴파일 타임에 푸시 될 수 있습니까? –

+0

STL과 부스트가 제대로 작동하는지 확신 할 수 없습니다. 일반적으로 반복자는 단순한 값 유형이라고 가정합니다. 다형성 디자인을 사용하려는 경우 값 유형을 사용할 수 없습니다. – visitor

+0

내가 개발중인 라이브러리는 사용자가 자신의 컨테이너를 정의하고 시스템에 등록 할 수있게해야합니다. 이 시스템은 등록 된 모든 컨테이너를 반복하고 처리하며, 나는 boost를 사용하는 코드 샘플을 보여 줬다. 또한이 컨테이너에 MyObject 유형을 자동으로 삽입해야합니다. 사용자가이 컨테이너 클래스를 확장하여 삽입 된 객체를 관리하는 데 사용하는 구조에 관계없이 원하는 순서대로 적용 할 수 있기를 바랍니다. – AdilYalcin

답변

1

복잡 할 것입니다.

이미 언급했듯이 일반적으로 iterator는 값을 의미 론적으로 사용해야합니다. 왜냐하면 일반적으로 주위에 복사되기 때문에 개체가 조각이됩니다.

class BaseContainer 
{ 
protected: 
    class BaseIteratorImpl; // Abstract class, for the interface 

public: 
    class iterator 
    { 
    public: 
    iterator(const BaseIteratorImpl& impl); 
    private: 
    BaseIteratorImpl* m_impl; 
    }; 

    iterator begin(); 
    iterator end(); 
}; // BaseContainer 

이어서, BaseIterator 전달 m_impl 모든 방법.

이렇게하면 다형성 코어를 사용하여 가치 의미 론적 구문을 구현할 수 있습니다.

분명히 딥 복사 의미론과 적절한 파괴를 처리해야합니다.

일부 노트 :

  • 게시 둘 모두 iteratorconst_iterator 클래스
  • 이름 STL 알고리즘과의 호환성을위한 방법 empty, size, begin, end 등 ...

당신 최대한의 호환성을 위해 운영자가 지원해야하는 개념 및 작업에 대한 도움이 필요하면 SGI Iterators을 확인하십시오.

+0

응답 해 주셔서 감사합니다. 이제 귀하의 접근 방식을 기반으로 맞춤형 반복기를 구현하려고합니다. 사용자는 결국 내부적으로 사용되는 컨테이너에 대한 사용자 지정 증분, 시작, 끝 작업을 정의해야합니다. 잘하면 곧 결과를보고 할 것입니다 :) – AdilYalcin

+0

std :: iterator 에서 제안한 public iterator 클래스를 상속 했으므로 BOOST_FOREACH에서도 작동하게 만들 수있었습니다. 올바른 방향, 그것은 내가 원하는대로, 최소한의 코드 오버 헤드와 함께 작동 :) – AdilYalcin

+0

그것은 항상 재미있는 문제가있는 사람들에게 도움이 될 수있는 즐거움 ... 또는 적어도 내가에 관심이있는 문제 :) –

관련 문제