2016-10-11 18 views
2

マップに2つの要素を挿入しても、次のコードでは1が印刷されるのはなぜですか?std:mapは2つのオブジェクトが等しいかどうかをどのようにチェックしますか?

#include <iostream> 
#include <map> 
#include <string> 
#include <utility> 

struct Foo 
{ 
    Foo(int bar, const std::string& baz) 
    : bar(bar) 
    , baz(baz) 
    {} 

    int bar; 
    std::string baz; 

    bool operator<(const Foo& rhs) const 
    { 
    if (bar < rhs.bar && baz < rhs.baz) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
    } 
}; 

int main() 
{ 
    Foo first(0, "test"); 
    Foo second(1, "test"); 
    std::map<Foo, std::string> m; 
    m.insert(std::make_pair(first, "test")); 
    m.insert(std::make_pair(second, "test1")); 
    std::cout << m.size() << std::endl; 
} 

insert()への2回目の呼び出しでは、既にマップにその項目があります。どうして?

私のprevious questionはタイプミスのため誤って閉じられました。私はinsertは、その項目がすでにコンテナに入っているかどうかを教えてくれることを知っています。

+6

'演算子:

はあなたのような何かを必要としています。あなたはしません。 – Pubby

+0

@Pubby「厳密な弱い注文」とはどういう意味ですか? – FrozenHeart

+0

http://stackoverflow.com/questions/979759/operator-and-strict-weak-ordering – Pubby

答えて

6

マップのinsert()は、要素間の等価性を判断するために入力したoperator<を使用します。 a < bb < aが両方とも偽の場合、2つの要素は等しいと見なされます。

operator<()は、必要な定義がないため、矛盾していますstrict weak ordering。たとえば、a.bar < b.barb.baz < a.bazを考えてみましょう。 a < bはfalseで、b < aはfalseであるため、マップはa == bと考えています。あなたの特定のケースでは、

firstsecond、その後、first.bazsecond.bazを比較し、両方の"test"あるので、両方の比較はfalseを返し、そして要素が等しいと見なされます。 < `厳しい弱い順序付けを定義する必要があります

bool operator<(const Foo& rhs) const 
{ 
    return std::tie(bar, baz) < std::tie(rhs.bar, rhs.baz); 
} 
+0

私は単に 'return bar FrozenHeart

+4

@FrozenHeart:No. –

+1

@FrozenHeartあなたが望むように、あなたが望むものを何でもできますが、それが[厳密な弱い注文制限](https://en.wikipedia.org/)に準拠していない場合は、 wiki/Weak_ordering#Strict_weak_orderings)、それは動作しません。そうではありません。あなたの場合、 'return bar WhozCraig

関連する問題