c++referenceoperator-overloadingordereddictionary

c++ map with custom key is size 3 but only iterates 2 elements?


I am trying to create an ordered map with my struct Tenor as key. Ordered map requires operator< , so I define it for my struct (currently just a placeholder, always returns true - this seems to cause problem Q1). In this example I insert 3 elements. But, as per below example, as I iterate through my map, it only iterates through 2 elements, not 3.

#include <iostream>
#include <map>
using namespace std;

struct Tenor {
    public:
        string _label;

        Tenor(string label = "3M")
        {
            _label = label;
        }

        // Placeholder for now
        bool operator<(Tenor const& obj) const
        {
            return true;
        }
};

void tenor_operator_ordered() {
    auto t1 = Tenor {"1M"};
    auto t2 = Tenor {"2M"};
    auto t3 = Tenor {"3M"};
    map<Tenor, int> mp;
    mp[t1] = 1; //insert
    mp[t3] = 3; 
    mp[t2] = 2;

    // Check if items are available?
    int item;
    item = mp.find(t1)->second;
    std::cout << item << '\n';
    item = mp.find(t2)->second;
    std::cout << item << '\n';
    item = mp.find(t3)->second;
    std::cout << item << '\n';

    cout << "Size: " << mp.size() << endl;
  
    // Printing Test objects in sorted order 
    for (auto x : mp) 
        cout << x.first._label << " " << x.second << endl;

}

My output:

469761104
469761104
469761104
Size: 3
3M 3
1M 1

Question 1: why for loop iterates through 2 elements only?

Question 2: why item is not the map's Value (for each given Key)? Update 1: thanks to the comments, it seems like my placeholder is not appropriate, and breaks the map algorithm.


Solution

  • As explained by the comments, using an arbitrary operator< which doesn't follow strict weak order is wrong. The operator overload must ensure that if a<b, then b>a. Otherwise it's undefined behaviour.