最近在用 map 和 set ,两个一起使用,set 作为 map 的 value。突然发现要获取 set 里的元素有点曲折啊,记录一下,方便以后随时查看。 我们知道 set 和 map 底层实现都是二叉树,自定义类型必须重载一个小于号运算符。
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <set>
enum label_type
{
LABEL_TYPE_ONE,
LABEL_TYPE_TWO,
LABEL_TYPE_THREE
};
struct label_map
{
int label;
enum label_type type;
};
bool operator<(const struct label_map& lhs, const struct label_map& rhs)
{
return lhs.label < rhs.label;
}
std::map<int, std::set<struct label_map>> map_set;
void getSetOfMap(int key, std::set<struct label_map> &label)
{
auto it = map_set.find(key);
if(it != map_set.end())
{
label = map_set[key];
}
}
void getSetElement(int key, struct label_map *label)
{
std::set<struct label_map> st;
getSetOfMap(key, st);
auto it = st.begin();
*label = *it;
}
int main()
{
struct label_map label_1 = {1001, LABEL_TYPE_ONE};
struct label_map label_2 = {1002, LABEL_TYPE_TWO};
struct label_map label_3 = {1003, LABEL_TYPE_THREE};
map_set[1].insert(label_1);
map_set[2].insert(label_2);
map_set[3].insert(label_3);
struct label_map label;
getSetElement(2, &label);
printf("label.label = %d, label.type = %d\n", label.label, label.type);
return 0;
}
使用 map 的时候一定要注意了,在获取 map 元素的时候,最好是用 find 一下先,如果喜欢用下标法 [] 来取的时候,则必须保证已经存在该 key,否则这个 [] 操作会插入一个新元素的, 新元素的值具体看类型了,因为它调用的是那个类型的构造函数。而 set 是没有 operator [] 操作的,要获取元素只能有 find() 了,上面的例子只取了 set 里的第一个。几个函数 可以改成这样,如果 map 里存在这个 key 则返回 0,否则非 0。
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <set>
enum label_type
{
LABEL_TYPE_ONE,
LABEL_TYPE_TWO,
LABEL_TYPE_THREE
};
struct label_map
{
int label;
enum label_type type;
};
bool operator<(const struct label_map& lhs, const struct label_map& rhs)
{
return lhs.label < rhs.label;
}
std::map<int, std::set<struct label_map>> map_set;
int getSetOfMap(int key, std::set<struct label_map> &label)
{
auto it = map_set.find(key);
if(it != map_set.end())
{
label = map_set[key];
return 0;
}
return -1;
}
int getSetElement(int key, struct label_map *label)
{
std::set<struct label_map> st;
if(0 == getSetOfMap(key, st))
{
auto it = st.begin();
*label = *it;
return 0;
}
return -1;
}
int main()
{
struct label_map label_1 = {1001, LABEL_TYPE_ONE};
struct label_map label_2 = {1002, LABEL_TYPE_TWO};
struct label_map label_3 = {1003, LABEL_TYPE_THREE};
map_set[1].insert(label_1);
map_set[2].insert(label_2);
map_set[3].insert(label_3);
int key = 4;
struct label_map label;
if(0 == getSetElement(key, &label))
{
printf("label.label = %d, label.type = %d\n", label.label, label.type);
}
else
{
printf("can't find key of %d\n", key);
}
return 0;
}
如果把函数改成这样,即直接用map 的 operator[] 操作符来取元素:
int getSetOfMap(int key, std::set<struct label_map> &label)
{
/*auto it = map_set.find(key);
if(it != map_set.end())
{
label = map_set[key];
return 0;
}
return -1;*/
label = map_set[key];
return 0;
}
其结果和期望就不一样了。