2

固有の要素の与えられたstd::set< T, less >、または入れ物。異種コンパレータです。つまり、別の型の値を type の値と比較できます。type のすべての値は一意ですが、(おそらく) typeの特定の値と同等の type の値がたくさんあります。未定義の動作ですか?std::map< T, less >lessUTTTU

たとえば、 type の値に相当するキーを持つコンテナ内の (1 つの) 要素を見つけたいとしますU。いずれか: 複数ある場合は、最初、最後、または中間のいずれか。utypeの値に相当するコンテナ内に複数の要素があることを私は知っていますU。使用std::set::findまたはstd::map::find機能できますか? 未定義の動作ですか?

例 (ここでは、許容範囲との不正確な比較0.2):

#include <set>
#include <iostream>

double const eps = 0.2;

struct less
{
    bool operator () (double l, double r) const { return l < r; }
    using is_transparent = void;
    bool operator () (int l, double r) const { return l + eps < r; }
    bool operator () (double l, int r) const { return l + eps < r; }
};

int main()
{
    std::set< double, less > s{0.0, 0.9, 1.0, 1.1, 2.0};
    for (auto it = s.find(1); it != std::end(s); it = s.find(1)) {
        std::cout << *it << ' ';
        s.erase(it);
    }
}

出力 (通常、順序は指定されていません):

0.9 1 1.1

上記のようなユニークな要素の連想順序付きコンテナを使用するのは UB ですか?

代わりにstd::multisetandを使用する必要がありますか?std::multimap

4

1 に答える 1

1

連想コンテナの要件表の前の説明テキストには、次のように記載されています。

klは、a[ sicc(r, kl) ] がとrのキー値でe分割([alg.sorting]) された値eです a。に関して分割される kuような値です。はと に関して分割された値であり、 を意味します。a!c(ku, r)keac(r, ke)!c(ke, r)c(r, ke)!c(ke, r)

そして、 、 、 の動作について説明a_tran.{find,count,equal_range}(ke)a_tran.lower_bound(kl)ますa_tran.upper_bound(ku)。したがって、要件は次のとおりです。

  • findcountおよびequal_range:
    • c(r, ke)コンテナー内の要素は、およびに関して分割する必要があります。!c(ke, r)
    • c(r, ke)暗示する必要があります!c(ke, r)
  • の場合lower_bound、コンテナ内の要素は に対して分割する必要がありますc(r, kl)
  • の場合upper_bound、コンテナ内の要素は に対して分割する必要があります!c(ku, r)

これらの要件を満たしていれば、コンテナー内の複数のキーに相当するもので異種ルックアップを使用しても問題はありません。結局のところ、元の提案の動機付けの例は、姓が「Smith」であるすべてsetの名前を検索することです。

于 2016-11-09T10:47:46.993 に答える