-1

I was working with the std::map library and I am trying to put a bunch of data into a map, I created a map to hold a date(time_t) and a float but when I try to add them in, my complier tells me "error: no match for 'operator<' (operand types are const &date, const &date)"

I tried creating an overloaded < operator, but still gave me the same error. I also tried to create a map outside of this program, and that did not need an operator< so how do I write this, and why is it even necessary?

here is the class that I am running it in:

class MutualFund
{
private:
    std::string ticker;
    Date oldestDate; //optional
    Date newestDate; // optional
    float newestNav; //optional
    map<Date,float> navHistory;
    set<Dividend> divHistory;
public:
    MutualFund(string i)
    {
    if( i == "VTSMX")
    {
    ifstream temp;
    string cell,cell2,tempstring;
    int i = 1;
    float tempFloat;
    temp.open("C:\\Users\\Lukas PC\\Desktop\\ass6files\\VTSMXshuffled.csv");
        //what needs to be done here:
        // turn the cell 1 into a Date object by turning it into a time_t
        //turn the cell2 into a float
        //populate the map
        while(!temp.eof())
        {
        // get the numbers from the spreadsheet
        getline(temp,cell,',');
        getline(temp,cell2,',');
        getline(temp,tempstring);

//make a time_t object from cell and put it into a Date object
        struct std::tm tm = {0};
        std::istringstream ss(cell.c_str());
        ss >> std::get_time(&tm, "%Y-%m-%d");
        //tm.tm_mday  = (tm.tm_mday -1);
        std::time_t time = mktime(&tm);
        Date mapDate;
        mapDate.setDate(time);


 //turn cell2 into a float
        if(isalpha(cell.at(1)) && isalpha(cell2.at(1)))
        {
        }
        else
        {
        cell2.erase(5,20);

        //cout << cell2<< endl;

        std::string::size_type sz;
        tempFloat = stof(cell2,&sz);
        navHistory[mapDate] = tempFloat;
        }
        i++;

        }
    }
    else if (i == "VFINX")
    {

    }
    }


   friend const bool operator< ( const Date &lhs ,const Date &rhs)
    {
        return true;
    }


};

Thanks for your help! always appreciated.

  • `friend bool operator< ( const Date &lhs ,const Date &rhs)` should be in Date class, not in `MutualFund`. – Jarod42 Mar 24 '18 at 03:19
  • A map needs a comparison operator because it is a sorted container or more specifically, a binary search tree. This is what allows for the fast searching since you can do one comparison and narrow down the range you're searching in by a half. – eesiraed Mar 24 '18 at 03:20
  • 1
    See [Why eof as loop condition is wrong](https://stackoverflow.com/q/5605125/9254539). – eesiraed Mar 24 '18 at 03:21
  • Like I said in the previous comment, the map needs the comparison operator for a reason, and having it always return true won't work. – eesiraed Mar 24 '18 at 03:22
  • You can use std::unordered_map if you don't need to keep the items sorted. #include – selbie Mar 24 '18 at 03:22
  • 1
    Edit your question to include a [mcve]. – Sid S Mar 24 '18 at 03:24
  • I understand that it does need to compare, what is the reason for it being there in the first place? – Lukas Pettersson Mar 24 '18 at 03:27
  • I'm not sure why you mean by "it". By the way, @selbie an `unordered_map` will need a hash function which I think is more difficult to implement than a comparison function. – eesiraed Mar 24 '18 at 04:12
  • Note that the comparison operator can be anything as long it satisfies 1. a < a == false 2. if a < b and b < c, a < c 3. if a < b, b < a == false. When you iterate over a map, the elements come out in the order of the comparison operator. – eesiraed Mar 24 '18 at 04:20

1 Answers1

3

The reason std::map requires a less than operator is because it is implemented as a red black tree. Not only that, but the elements in a map are guaranteed to be ordered. Thus, it requires that the type it is referencing as the key be comparable via operator<.

If you don't need the elements to be ordered then you could use std::unordered_map. However, for user defined types you would have to explicitly define and overload std::hash.

With just one of operators overloaded it can determine if one is greater or if they are both equal.

Anyways, the issue with your code is the fact that you are trying to create the less than operator outside the main class. Move the overloaded operator< inside of the Date class and it should work.

Rabster
  • 933
  • 1
  • 7
  • 11
  • `std::unordered_map` requires a hashable key. And if strict weak ordering is not implemented, it's fairly likely that the key is not hashable either, and requires a hashing implementation to be explicitly defined. – Sam Varshavchik Mar 24 '18 at 03:44
  • that does get me further, but it now crashes and returns "-1073741571 (0xC00000FD)" I read up on it and it seems that this is caused by excessive recursion , though not sure what is causing this. – Lukas Pettersson Mar 24 '18 at 04:02
  • @LukasPettersson Try a debugger? – eesiraed Mar 24 '18 at 04:14