2012-11-13 5 views
16

イテレータを指定すると、このイテレータが参照するコレクションに対して正しい比較関数を取得/使用できますか?イテレータを指定してコンテナの比較関数を取得する

たとえば、のは、私は一般的なアルゴリズムを書いていると仮定しましょう:

template <class InIt, class T> 
void do_something(InIt b, InIt e, T v) { 
    // ... 
} 

、のは、私が[b..e)vを見つけるように、簡単な何かをしたいとしましょう。 bestd::vectorを超えるイテレータの場合は、単にif (*b == v) ...を使用します。しかし、beは、std::map以上のイテレータであるとします。この場合、I のキーと比較するだけで、マップに含まれている値のタイプ全体ではありません。

質問には、それらのイテレータがマップ内にある場合、キーを比較するだけのマップの比較関数を取得するにはどうすればよいですか?同時に、私は盲目的に私がmapで働いていると仮定したくありません。たとえば、イテレータがsetを指していたら、そのために定義された比較関数を使用したいと思います。set彼らがvectorまたはdequeを指していた場合、おそらく==を使用する必要があります。なぜなら、それらのコンテナには比較関数が定義されていないからです。

ああ、ほとんど忘れてしまった:多くの場合、コンテナに含まれている要素のoperator==ではなく、operator<に相当するものがあることに気がつきました。

+0

今すぐ回答を書く時間はありませんが、これはhttp://en.cppreference.com/w/cpp/container/map/key_compに役立ちます。うーん、それほど多くはない。トリッキーな部分はコンテナを取得しています。 –

+0

私はあなたの 'set'のために混乱しています。 'set'のコンパレータはtotal-orderでなければなりません。これは' operator == 'の場合ではありません。 – pmr

+0

マップエントリのキーだけを比較する場合とエントリ全体を比較する場合とで同じではありませんか? [編集]もちろん、そうではありません。マップされた部分に等価操作がないかもしれません。 –

答えて

6

イテレータから基になるコンテナタイプ(そのようなコンテナがあれば)にマップする標準的な方法はありません。いくつかの発見的手法を使用してどのコンテナを決定しようとするかもしれませんが、それは簡単ではなく、おそらく保証されないでしょう。例えば

、あなたは* VALUE_TYPE *これはstd::mapと種類Kを抽出した後にも及びTタイプかどうかを判断するためにメタ関数を使用しようとすることができることを示唆している、std::pair<const K, T>であるかどうかを判断するためにメタ関数を使用することができます反復子の種類は、,Yの特定の組み合わせに一致します。std::map<K,T,X,Y>::iteratorまたはstd::map<K,T,X,Y>::const_iteratorの種類が一致します。 に十分な可能性がマップの場合

を決定イテレータがstd::mapを意味するが、あなたはそれを使用しても、抽出することができても、ことに注意しなければならないこと(すなわち、成功の高い確率で推測)比較器のタイプXは、に複製するのに十分ではない一般的なケースではコンパレータです。珍しい(と推奨されない)コンパレータは状態を持つことができますが、コンテナに直接アクセスすることなくコンパレータの特定の状態を知ることはできません。また、このタイプのヒューリスティックが役に立たない場合もあります。std::vector<>の実装の中には、イテレータの型が直接ポインタである場合があります。その場合、イテレータと配列を区別することはできません。std::vector<>同じ基本タイプの

11

イテレータはコンテナに接続する必要はないため、必ずしも接続されていないコンテナに関する詳細はわかりません。イテレータの抽象化は必須です。イテレータは、シーケンスがどこから来るかに関係なく、シーケンスを区切ります。コンテナについて知る必要がある場合は、コンテナを取るアルゴリズムを記述する必要があります。

+2

例:いくつかの 'string'と' vector'には、イテレータがベアポインタとして実装されていました(シーケンシャルな連続したバッファを利用しています)。 –

+0

引数をコンテナとして扱っても、 'Sequence'と' AssociativeContainer'を区別するためには、依然としてトリックに頼る必要があります。私は 'is_associative_container'を書くのは難しいと思います。 – pmr

+0

@pmr:標準コンテナのみをサポートしたいのであれば、その特性は単純です...タイプが 'std :: map'、' std :: multimap'、 'std :: set '、' std :: multiset'(そしてそれらをサポートする必要があれば順序付けされていないバージョンですが、* comparator *という概念はそこにはありません) –

3

残念なことに、イテレータは、それらを含むコンテナについては常に知っているとは限りません(標準コンテナにはまったくない場合もあります)。 iterator_traitsでもvalue_typeに関する情報しかありませんが、具体的にどのように比較するかは分かりません。

代わりに、標準ライブラリからインスピレーションを引き出しましょう。すべての関連コンテナ(mapなど)は、std::findを使用するのではなく、独自のfindメソッドを持っています。 の場合はそのようなコンテナにstd::findを使用する必要があります。あなたはfind_ifを使用します。

あなたの解決策のように聞こえるのは、関連するコンテナの場合、エントリを比較する方法を示す述語を受け入れるdo_something_ifが必要であるということです。

関連する問題