stl::set 的一个缺陷
stl::set 什么都好,就一点不好:不能仅仅通过 key去查找元素。
例如 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#include <set> struct my_struct { int key; int value1; int value2; //…………… explicit my_struct(int key_) // explicit 禁止将 int 悄悄转化为 my_struct : key( key_) { } struct compare { bool operator()(const my_struct& l, const my_struct& r) const { return l.key < r. key; } bool operator()(const int key, const my_struct& r) const { return key < r .key; } bool operator()(const my_struct& l, const int key) const { return l.key < key; } }; struct ptr_compare { bool operator()(const my_struct* l, const my_struct* r) const { return l->key < r-> key; } bool operator()(const int key, const my_struct* r) const { return key < r ->key; } bool operator()(const my_struct* l, const int key) const { return l->key < key; } }; }; //…… typedef std:: set<my_struct , my_struct::compare> my_set_type ; typedef std:: set<my_struct*, my_struct::ptr_compare> my_ptr_set_type ; //…… void foo() { my_set_type my_set; my_struct x( 1); //.... my_set. insert(x ); my_struct y( 100); my_set. insert(y ); //..... // 错误,不能这样,如果把 explicit my_struct(int key_) // 中的 explicit 去掉,这样就可以,但仍然(悄悄地) // 增加了创建一个 my_struct 的开销 my_set_type:: iterator iter2 = my_set. find(100 ); // 只能这样 my_struct asKey(100 ); my_set_type:: iterator iter1 = my_set. find(asKey ); // 或者这样,都增加了创建一个 my_struct 的开销 my_set_type:: iterator iter3 = my_set. find(my_struct (100)); } void foo2() { my_ptr_set_type my_ptr_set; my_struct x( 1); //.... my_ptr_set. insert(&x ); my_struct y( 100); my_ptr_set. insert(&y ); //..... // 错误,不能这样 my_ptr_set_type:: iterator iter2 = my_ptr_set. find(100 ); // 只能这样 my_struct asKey(100 ); my_ptr_set_type:: iterator iter1 = my_ptr_set. find(&asKey ); // 或者这样 my_ptr_set_type:: iterator iter3 = my_ptr_set. find(&my_struct (100)); } // 如果 std::set::find 是个 template member function: // template<typename Key> iterator find(Key key) { ... } // 那么 my_ptr_set.find(100) 就是合法的,并且不会增加创建一个对象的开销 |
你应该看过boost::multi_index_container吧,想怎么查就怎么查,呵呵,比set好多了。理论效率也更高。
呵呵,刚刚看过,boost::multi_index::multi_index_container 真是一个出色的容器,几乎满足了我所有需求,但是还有一点点不太满足——多个 Index 始终是同步的,有时我需要 Sequence 不同步。