STLのset
set::eraseがvoidなのが理解出来ない。なぜiteratorを返さないのか。まとめて複数の要素を削除したいときとか、不便じゃないのか。逆にinsertの方はboolで良いと思う。map::eraseも同じ。
さらに、setクラスにはメンバ関数として、isSubsetOf(set)があっても良いのではないか。集合の包含関係は順序(厳密弱順序と言うらしい)にはならないのでoperator<は今のままで良いと思うが、operator+, operator-, operator* もあって良いと思う。
#include <set> template <typename Key, typename Compare1, typename Allocator1, typename Compare2, typename Allocator2> bool isSubset(const std::set<Key, Compare1, Allocator1>& A, const std::set<Key, Compare2, Allocator2>& B){ for(typename std::set<Key, Compare1, Allocator1>::const_iterator i=A.begin(); i != A.end(); ++i){ if(B.find(*i) == B.end()){ return false; } } return true; }
template <typename Key, typename Compare, typename Allocator1, typename Allocator2> bool isSubset(const std::set<Key, Compare, Allocator1>& A, const std::set<Key, Compare, Allocator2>& B){ typename std::set<Key, Compare, Allocator1>::const_iterator i = A.begin(); typename std::set<Key, Compare, Allocator2>::const_iterator j = B.begin(); while(i != A.end()){ if(j == B.end() || Compare()(*i, *j)){ return false; } else if(*i == *j){ ++i; ++j; } else{ ++j; } } return true; }
みたいな感じ。
あと、binary_searchに渡すiteratorってForwardIteratorで良くて、RandomAccessIteratorである必要は無いみたいで、実際setに対しても出来るみたいだが、なぜだろう。beginとendの中間点が計算出来ないとbinary_search出来ないように思うんだけれど、ForwardIteratorじゃ、そこまでひたすらインクリメントしないといけないのでは?(たしかにSGIのコードを見るとそうなっている、、、binary_searchなのに計算量が log n でないらしい)