1

I have class like this .

class Time
{
  public:
    int seconds, minutes, hours;
};

I want to use unordered_map with key as Time. What is a better way of doing this :

1) use unordered_map where string is concatenation of fields of class. Eg convert 56:12:1 to a string and use this as key

2) Defining something like discussed here

Please help me choose based on current use case :)

danish sodhi
  • 1,793
  • 4
  • 21
  • 31

1 Answers1

3

Why would you want to convert the time to string first? Your goal should be a wide spreading of hash values with an inexpensive hash function, right? Also this is real time? In which case you get away with unsigned short for the members.

#include <unordered_map>
#include <functional>
#include <string>
#include <iostream>

class Time {
public:

  Time(unsigned short h = 0, unsigned short m = 0, unsigned short s = 0) :
    hours(h), minutes(m), seconds(s) {}

  bool operator==(Time const& other) const {
    return (seconds==other.seconds &&
            minutes==other.minutes &&
            hours==other.hours);
  }

  unsigned short hours, minutes, seconds;

};

std::ostream& operator<<(std::ostream& o, Time const& t) {
  o << t.hours << ":" << t.minutes << ":" << t.seconds;
  return o;
}

namespace std {
  template<> struct hash<Time> {
    size_t operator()(Time const& t) const {
      return size_t(((t.seconds * 37 + t.minutes) * 37 + t.hours) * 37);
    }
  };
}

int main() {
  std::unordered_map<Time, std::string> u;
  u[Time(3,15,31)] = std::string("Hello world");
  u[Time(3,15,32)] = std::string("foo");
  u[Time(3,15,32)] = std::string("bar");
  for (auto const& i : u) {
    std::cout << i.first << " - " << i.second << std::endl; 
  } 
  return 0;
}
Kaveh Vahedipour
  • 3,412
  • 1
  • 14
  • 22