You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:45:16