これらのオーバーロードを提供しないのには、適切な "設計哲学" の理由があります。特に、STL コンテナとアルゴリズムの相互作用全体は、異なるイテレータの概念を通過するように設計されているため、これら 2 つの部分は独立したままであり、すべてのアルゴリズムをオーバーロードすることなく新しいコンテナ タイプを定義できます。すべてのコンテナをオーバーロードする必要のない新しいアルゴリズム。
これらの設計上の選択を超えて、これらのアルゴリズム (並べ替え、下限など) を/list
などの特別なコンテナーに対してオーバーロードできない非常に技術的な理由があります。その理由は、通常、イテレーターを親コンテナーに明示的に接続する理由がないためです。つまり、リスト コンテナーからリスト イテレーター (begin/end) を取得できますが、リスト イテレーターからリスト コンテナー (への参照) を取得することはできません。同じことが map / set イテレータにも当てはまります。イテレータは、親コンテナに対して「ブラインド」になるように実装できます。たとえば、次のようなコンテナmap
set
list
通常、データメンバーとして、ヘッドノードとテールノードへのポインター、およびアロケーターオブジェクトが含まれますが、イテレーター自体 (通常はノードへのポインターのみ) は、ヘッド/テールまたはアロケーターについて知る必要はありません。前/次のリンクポインタをたどって、リスト内を前後に移動します。したがって、std::sort
for のオーバーロードを実装する場合は、list
sort 関数に渡された反復子からリスト コンテナーを取得する方法はありません。そして、あなたが言及したすべてのケースで、それらの特別なコンテナーに適したアルゴリズムのバージョンは、「ブラインド」イテレーター レベルではなく、コンテナー レベルで実行する必要があるという意味で「集中化」されています。そのため、メンバー関数として意味があり、反復子からそれらに到達できないのはそのためです。
ただし、コンテナーに関係なくこれらのアルゴリズムを呼び出す汎用的な方法が必要な場合は、必要に応じてオーバーロードされた関数テンプレートをコンテナー レベルで提供できます。次のように簡単です。
template <typename Container>
void sort_container(Container& c) {
std::sort(begin(c), end(c));
};
template <typename T, typename Alloc>
void sort_container(std::list<T, Alloc>& c) {
c.sort();
};
template <typename Key, typename T, typename Compare, typename Alloc>
void sort_container(std::map<Key, T, Compare, Alloc>&) { /* nothing */ };
//... so on..
ここでのポイントは、既に STL コンテナーに結び付けられている場合、必要に応じてこの方法で STL アルゴリズムに結び付けることができるということです...ただし、C++ 標準ライブラリがこの種のコンテナーを強制することを期待しないでくださいコンテナとアルゴリズムの間の相互依存。誰もがそれらを望んでいるわけではないためです (たとえば、多くの人は STL アルゴリズムが本当に好きですが、STL コンテナは好きではありません (多くの問題があります))。