2016-11-09 33 views
2

給定std::set< T, less >std::map< T, less >容器中的獨特元素。 less是異構比較器。即它可以將一些另外的類型U的值與類型T的值進行比較。儘管T類型的所有值都是唯一的,但是(可能)有大量值爲T的值,它們的值等於U類型的某個特定值。它是不確定的行爲?映射或設置有透明比較器和異構元素的非唯一元素

說,我想在容器中找到(一個)元素,它具有鍵值,相當於U類型的值。任何一個:無論是第一個,最後一個還是其中的一個,如果多於一個。我知道,容器中有多個元素,它們相當於U類型的值u。我可以使用std::set::findstd::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::multiset還是std::multimap代替?

+0

我認爲你的意思是「大量的**'U' **值等於給定的'T'」 –

+0

你的例子'less'在比較int和double時沒有定義嚴格的弱排序。這看起來很可能是悲傷的原因。 OTOH,比較像'operator()(std :: pair lhs,double rhs){return lhs.first

+0

@MartinBonner號完全如上所述。上面的例子說明了這種可能 – Orient

回答

1

關聯容器要求表之前的解釋性文本說:

kl是一個值,使得a [原文如此]被分區([alg.sorting]) 相對於c(r, kl),與ree的關鍵值 a; kua相對於分割的值; kea相對於 到c(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)進行分區。

如果您滿足這些要求,那麼在容器中使用與多個鍵等效的東西來使用異構查找沒有任何問題。畢竟,the original proposal中的激勵性示例是關於在名稱的set中查找姓氏爲「Smith」的所有人。