2012-01-28 67 views
0

公衆視野我有一個祕密範圍的Boost.BiMap的一類,我想出口的該地圖的一部分公衆視野。我有下面的代碼的兩個問題:暴露私人範圍的Boost.BiMap迭代

class Object { 

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

    PointMap point_map; 

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

的第一個問題是,如果我的迭代的方法來獲取與Value關聯是正確的Point的。以下是我用來遍歷點的代碼。我的問題是,如果我循環正確,因爲我發現,我必須包括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 */ 
} 

第二個問題是什麼是不暴露bimap的迭代器提供GetPoints(在???返回類型以上)的公衆視野,因爲它似乎呼叫者就必須瞭解point_map.right.end()的最佳途徑。任何有效的結構(如引用列表或集合)都可以工作,但我在創建集合方面有點遺憾。

謝謝!

回答

0

第一個問題:

由於您使用您的bimap類型的右側unordered_multiset_of集合類型,這意味着它將與std::unordered_multimap兼容的接口。 std::unordered_multimap具有成員函數equal_range(const Key& key)它返回迭代器的std::pair,一個指向具有指向一個過去具有相同的關鍵要素的範圍的端部所需的密鑰和一個第一個元素。使用它可以使用匹配鍵迭代範圍,而無需將鍵與迭代條件中的值進行比較。

請參閱參考資料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; } 
}; 

這是一個好主意,使之不可複製,不可移動和不可分配,因爲用戶可以以其他方式保持代理類的副本,並嘗試訪問它(就像我通過刪除相關成員函數上面完成)之後迭代器可能失效。

第一種方式是指寫更少的代碼,第二裝置呈現一種較爲常見的接口給用戶(以及允許在代理類隱藏更多的東西,如果以後需要修改實現)。

+0

關於第二個問題的第一種方法,PointMap是否需要公開作用域?我可以爲公共接口使用某種類型的泛型迭代器嗎? – 2012-01-28 22:19:06

+0

PointMap仍然可以是私人的。我的示例代碼中的typedef match_iterator需要是公開的,因此它可以被類之外的代碼使用。 – user450018 2012-01-29 08:49:35