16

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

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

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

vここで、 find inのような簡単なことをしたいとしましょう[b..e)beが a のイテレータである場合、std::vector単純に を使用できますif (*b == v) ...bただし、とeが a のイテレータであると仮定しましょうstd::map。この場合、マップに含まれている値の型全体ではなく、キーのみを比較する必要があります。

問題は、これらのイテレータをマップに指定した場合、キーのみを比較するマップの比較関数を取得するにはどうすればよいかということです。同時に、mapどちらか一方を扱っているとやみくもに想定したくありません。たとえば、反復子が を指している場合、その に対してset定義された比較関数を使用したいと思いますsetvectorそれらがまたはを指している場合、これらのコンテナーには比較関数が定義されていないため、dequeおそらく を使用する必要があります。==

ああ、ほとんど忘れていました。多くの場合、コンテナーには、含まれる要素ではoperator<なく、同等のものしかないことがわかりました。それを使用できてもまったく問題ありません。operator==

4

3 に答える 3

11

イテレーターはコンテナーに接続する必要がないため、必ずしも接続されていないコンテナーに関する詳細は提供されません。これが本質的な反復子の抽象化です。反復子は、シーケンスがどこから来ているかに関係なく、シーケンスを区切ります。コンテナーについて知る必要がある場合は、コンテナーを使用するアルゴリズムを作成する必要があります。

于 2012-11-13T16:28:06.610 に答える
6

イテレーターから基礎となるコンテナー・タイプにマップする標準的な方法はありません (そのようなコンテナーが存在する場合)。いくつかのヒューリスティックを使用してどのコンテナーかを判別できる場合がありますが、それは単純ではなく、おそらく保証もされません。

たとえば、メタ関数を使用して *value_type* が であるかどうかを判断できます。これは、型を抽出した後に and でstd::pair<const K, T>ある可能性があるというヒントであり、メタ関数を使用して、反復子の型とorの型かどうかを判断してみてください。 、 の特定の組み合わせに一致します。std::mapKTstd::map<K,T,X,Y>::iteratorstd::map<K,T,X,Y>::const_iteratorXY

イテレータが a を参照していると判断する(つまり、成功する可能性が高いと推測する) のに十分なマップの場合、それを使用してコンパレータstd::mapの型を抽出することさえできる場合でも、一般的なケースでコンパレータを複製Xするには不十分です。珍しい (そして推奨されない) コンパレーターは状態を持つことができますが、コンテナーに直接アクセスしない限り、コンパレーターの特定の状態がどれであるかはわかりません。また、このタイプのヒューリスティックが役に立たない場合もあることに注意してください。イテレータ型の一部の実装では直接ポインタであり、その場合、「イテレータ」から配列への変換とイテレータから配列への変換を区別することはできません。std::vector<>std::vector<>同じ基本型の。

于 2012-11-13T16:39:04.527 に答える
3

残念ながら、イテレータはそれらを含むコンテナについて常に知っているわけではありません(また、標準のコンテナにまったく含まれていない場合もあります)。iterator_traits比較する方法を具体的に教えていないvalue_typeに関する情報を持っているのは1つだけです。

代わりに、標準ライブラリからインスピレーションを得ましょう。すべての連想コンテナ(など)には、を使用するのではなくmap、独自のメソッドがあります。そして、そのようなコンテナで使用する必要がある場合、使用しません。を使用します。findstd::findstd::findfind_if

あなたの解決策は、連想コンテナの場合do_something_if、エントリを比較する方法を指示する述語を受け入れるが必要であるように思われます。

于 2012-11-13T16:53:54.883 に答える