C++中map/unordered_map使用char*作为键的问题及解决
问题描述
我正在编写一个简易Web服务器,在HTTP类的构造函数中解析请求,变量l存储METHOD PATH HTTPVERSION(例如GET / HTTP/1.1)。将代表请求方法的变量m传入map_methods函数时,无法返回正确的枚举值;但传入字面量"GET"或"POST"时却能正常工作,请问这是什么原因?
相关代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <map> #include "http.h" using std::map; Http::Http(char *request) { char *l, *h, *k, *m, *p, *t, *v; if (!strlen(request)) goto err; for (int i = 0; i < strlen(request) - 1; i++) if (request[i] == '\n' == request[i + 1]) request[i + 1] = '|'; l = strtok(request, "\n"); h = strtok(__null, "|"); k = strtok(__null, "|"); m = strtok(l, " "); p = strtok(__null, " "); t = strtok(__null, " "); v = strtok(t, "HTTP/"); this->uri = p; this->version = (float)atof(v); this->method = this->map_methods(m); return; err: { perror("Error parsing request"); exit(1); } } int Http::map_methods(const char *m) { printf("%s\n", m); map<const char *, int> methods = { {"GET", GET}, {"POST", POST}, {"PUT", PUT}, {"HEAD", HEAD}, {"PATCH", PATCH}, {"DELETE", DELETE}, {"CONNECT", CONNECT}, {"OPTIONS", OPTIONS}, {"TRACE", TRACE}, }; printf("%i\n", methods[m]); return methods[m]; }
解决方案(编辑补充)
方案一:自定义比较结构体
定义字符串比较结构体,替换std::map默认的指针比较逻辑:
struct strcmp_s { bool operator()(char const *s1, char const *s2) const { return strcmp(s1, s2) < 0; } };
将map的定义修改为:
std::map<const char *,int, strcmp_s>
方案二:改用std::string作为键
直接使用std::map<std::string,int>,无需修改其他代码即可解决问题。
二次编辑补充
上述自定义比较结构可正常用于std::map,但适配std::unordered_map时需要自定义哈希或键比较函数,这类方案偏离了原本的问题核心,用char*作为map/unordered_map键的问题仍未得到理想解答。
作为C++新手,我认为用std::string完全替代char*的方案被过度推荐,并不适配所有场景。后来发现std::string_view是更好的选择,可直接适配std::map和std::unordered_map,以下是可直接使用的模板:
#include <string_view> #include <map> #include <unordered_map> template <typename T> using dic = std::map<std::string_view, T>; template <typename T> using unordered_dic = std::unordered_map<std::string_view, T>;
内容的提问来源于stack exchange,提问作者MurderByProxy
相关产品推荐
相关产品推荐

