2012-01-28 3 views
0

개인적으로 범위가 지정된 Boost.BiMap을 클래스에 포함하고 있으며이 맵의 일부에 대한 공개 뷰를 내보내려고합니다. 나는 다음과 같은 코드에 대한 두 가지 질문이있다 : 반복 내 방법은 올바른입니다 Value과 관련된 Point 년대를 얻을 경우사적 영역의 공개 뷰 공개 Boost.BiMap 반복자

class Object { 

    typedef bimap< 
     unordered_set_of<Point>, 
     unordered_multiset_of<Value> 
    > PointMap; 

    PointMap point_map; 

public: 
    ??? GetPoints(Value v) { 
    ... 
} 

첫 번째 질문입니다. 아래는 포인트를 반복 할 때 사용하는 코드입니다. 내 질문은 정확히 내가 반복 할 경우, 내가 it->first == value 조건을 포함해야한다는 것을 알았 기 때문에 이것이 잘 알려지지 않을 수도있는 더 나은 인터페이스를 제공해야하는지 확실하지 않았기 때문입니다.

PointMap::right_const_iterator it; 
it = point_map.right.find(value); 
while (it != point_map.right.end() && it->first == val) { 
    /* do stuff */ 
} 

두 번째 질문은 발신자에 대한 point_map.right.end()을 알고 있어야한다는 것 때문에 bimap 반복자를 노출하지 않고합니다 (??? 반환 형식 위) GetPoints의 공개 뷰를 제공하는 가장 좋은 방법입니다 것입니다. 참조 또는 집합 목록과 같은 효율적인 구조는 작동하지만 컬렉션을 만드는 방법에 대해서는 약간 분실되어 있습니다.

감사합니다.

답변

0

첫 번째 질문 :

당신이 당신의 bimap 유형의 오른쪽에 대한 unordered_multiset_of 수집 유형을 사용하고 있기 때문에, 그것은 std::unordered_multimap와 호환 인터페이스를 가질 것을 의미합니다. std::unordered_multimap에는 std::pair 개의 반복자를 반환하는 멤버 함수 equal_range(const Key& key)이 있습니다. 하나는 원하는 키가있는 첫 번째 요소를 가리키고 다른 하나는 같은 키를 가진 요소 범위의 끝을지나 하나를 가리 킵니다. 이를 사용하면 키를 반복 조건의 값과 비교하지 않고 일치하는 키로 범위를 반복 할 수 있습니다.

참조 용으로 http://www.boost.org/doc/libs/1_41_0/libs/bimap/doc/html/boost_bimap/the_tutorial/controlling_collection_types.htmlhttp://en.cppreference.com/w/cpp/container/unordered_multimap/equal_range을 참조하십시오.

번째 질문 :

반면 매칭 값이 요소에 대한 포인터 또는 참조 목록 또는 다른 실제 용기를 구성하고 항상 O 요구하는 (N) 공간가는 이후 즉 비효율적 반환 사용자가 원래의 bimap에서 범위를 반복하도록하면 O (1) 메모리 만 필요한 두 개의 반복자 만 반환하면됩니다.

이터레이터를 직접 반환하는 멤버 함수를 작성할 수 있습니다 (예 :

typedef PointMap::right_const_iterator match_iterator; 

std::pair<match_iterator, match_iterator> GetPoints(Value v) { 
    return point_map.right.equal_range(v); 
} 

하거나 (시작)과 end() 멤버 함수 두 반복자를 반환하고 GetPoints() 멤버 함수는 해당 유형의 객체를 반환해야함으로써 용기와 같은 인터페이스를 제공 프록시 클래스를 작성할 수 있습니다 :

class MatchList { 

    typedef PointMap::right_const_iterator iterator; 

    std::pair<iterator, iterator> m_iters; 

public: 

    MatchList(std::pair<iterator, iterator> const& p) : m_iters(p) {} 

    MatchList(MatchList const&) = delete; 

    MatchList(MatchList&&) = delete; 

    MatchList& operator=(MatchList const&) = delete; 

    iterator begin() { return m_iters.first; } 

    iterator end() { return m_iters.second; } 
}; 

사용자가 다른 프록시 클래스의 사본을 보관하고 액세스하려고 할 수 있기 때문에 (필자는 관련 멤버 함수를 삭제하여 위 할 것 같은) 그것은, uncopyable 이동할 수없는 및 이상 할당 할 수 있도록하는 것이 좋습니다 나중에 이터레이터가 무효화 될 수 있습니다.

첫 번째 방법은 적은 코드를 작성하는 것을 의미하고 두 번째는 사용자에게보다 일반적인 인터페이스를 제공함을 의미합니다. 나중에 구현을 수정해야하는 경우 프록시 클래스에 더 많은 내용을 숨길 수 있습니다.

+0

두 번째 질문에 대한 첫 번째 접근 방식과 관련하여 PointMap을 공개적으로 범위 화해야합니까? 공개 인터페이스에 일종의 일반 이터레이터를 사용할 수 있습니까? –

+0

PointMap은 여전히 ​​개인이 될 수 있습니다. 예제 코드의 typedef match_iterator는 public이되어야 클래스 외부의 코드에서 사용할 수 있습니다. – user450018