c++ how to make your own class a valid key type for std::map?

In Java, if you want your own class to be a valid key type of the container, you just need to make it implement the interface "Comparable", and then it'll work properly.

 

How about in C++? I was wondering whether C++ has offered some kind of mechanism that acts like an interface in Java to enforce some "contract" to which a type must conform, such as std::map, it's obvious its key type must be "comparable".

 

How to ensure that the type indeed conform to the contract, through some kind of "interface" mechanism or what? Will the compiler do the work at compile time to check whether a type conform to the contract or not?

 

I looked up some C++ references in cppreference.com and cplusplus.com, I just couldn't find any useful information about what contract std::map require on its key type.

 

By search on stackoverflow.com, I found this: http://stackoverflow.com/questions/19937260/use-user-defined-struct-as-the-key-for-map-c

 

So maybe i just need to define an operator< for that type ?

 

Try it. Notice that in main.cpp, if you remove the operator< on Box type. The compiler will complain when you use Box as a key type of std::map. So, the compiler did ensure that Box must conform to the contract defined by operator<.

 

But how to implement std::map so that it would offer the information to the compiler: the std::map::key_type must be a type that has an overloaded operator< definition, you must check this at compile time. (I'm asking this question on stackoverflow.com, waiting for answer, http://stackoverflow.com/questions/27078796/how-is-stdmap-implemented-so-it-can-require-its-key-type-to-be-comparable)

 

main.cpp

 1 #include <iostream>
 2 #include <map>
 3 
 4 using namespace std;
 5 
 6 class Box {
 7     friend ostream& operator<<(ostream &os, const Box &b);
 8     friend bool operator<(const Box &left, const Box &right);
 9 public:
10     Box(int i, double d);
11     ~Box();
12 private:
13     int i;
14     double d;
15 };
16 
17 Box::Box(int _i, double _d):i(_i), d(_d) {}
18 
19 Box::~Box() {}
20 
21 bool operator<(const Box &left, const Box &right)
22 {
23     return (left.i < right.i);
24 }
25 
26 ostream& operator<<(ostream &os, const Box &b)
27 {
28     os << b.d;
29     return os;
30 }
31 
32 int main()
33 {
34     Box b1(3,2), b2(2,1), b3(0, 9);
35     map<Box, int> bmap;
36     bmap.insert(pair<Box,int>(b1, 10));
37     bmap.insert(pair<Box,int>(b2, 10));
38     bmap.insert(pair<Box,int>(b3, 10));
39     for (map<Box,int>::iterator iter = bmap.begin(); iter != bmap.end(); ++iter)
40     {
41         cout << iter->first << " ";
42     }
43     cout << endl;
44     return 0;
45 }

 

posted @ 2014-11-22 22:24  rldts  阅读(320)  评论(0编辑  收藏  举报