Using char*as a key in std::map

Jos*_*ald 74 c++ stdmap map

我试图弄清楚为什么以下代码不起作用,我假设使用char*作为键类型是一个问题,但是我不知道如何解决它或为什么它发生.我使用的所有其他功能(在HL2 SDK中)使用char*这样std::string会导致很多不必要的复杂化.

std::map<char*, int> g_PlayerNames;

int PlayerManager::CreateFakePlayer()
{
    FakePlayer *player = new FakePlayer();
    int index = g_FakePlayers.AddToTail(player);

    bool foundName = false;

    // Iterate through Player Names and find an Unused one
    for(std::map<char*,int>::iterator it = g_PlayerNames.begin(); it != g_PlayerNames.end(); ++it)
    {
        if(it->second == NAME_AVAILABLE)
        {
            // We found an Available Name. Mark as Unavailable and move it to the end of the list
            foundName = true;
            g_FakePlayers.Element(index)->name = it->first;

            g_PlayerNames.insert(std::pair<char*, int>(it->first, NAME_UNAVAILABLE));
            g_PlayerNames.erase(it); // Remove name since we added it to the end of the list

            break;
        }
    }

    // If we can't find a usable name, just user 'player'
    if(!foundName)
    {
        g_FakePlayers.Element(index)->name = "player";
    }

    g_FakePlayers.Element(index)->connectTime = time(NULL);
    g_FakePlayers.Element(index)->score = 0;

    return index;
}
Run Code Online (Sandbox Code Playgroud)

GWW*_*GWW 127

你需要给地图提供一个比较函子,否则它会比较指针,而不是它指向的以null结尾的字符串.通常,只要您希望地图键成为指针,就会出现这种情况.

例如:

struct cmp_str
{
   bool operator()(char const *a, char const *b) const
   {
      return std::strcmp(a, b) < 0;
   }
};

map<char *, int, cmp_str> BlahBlah;
Run Code Online (Sandbox Code Playgroud)

  • 不,`strcmp`返回正整数,零整数或负整数.map functor需要在less-than和false之间返回true. (23认同)
  • 哦,对不起,我的不好,发帖前没想到.让评论留在那里,给我的祖先带来耻辱:) (23认同)
  • @Armen:我认为它不起作用,因为第3个模板参数需要像`f(a,b)= a <b`,而不是`f(a,b)=(-1如果a <b,1如果a> b,0 else)`. (4认同)
  • 实际上他只能将`&std :: strcmp`作为第三个模板参数传递 (2认同)
  • 在我测试时,它必须在bool operator()之后使用const(char const*a,char const*b),就像bool operator()(char const*a,char const*b)const {blabla (2认同)

Pab*_*ruz 44

你不能使用,char*除非你绝对100%确定你将使用完全相同的指针访问地图,而不是字符串.

例:

char *s1; // pointing to a string "hello" stored memory location #12
char *s2; // pointing to a string "hello" stored memory location #20
Run Code Online (Sandbox Code Playgroud)

如果您访问地图,s1您将获得与访问地图不同的位置s2.

  • 除非您定义自己的比较器,否则如接受答案中所述。 (4认同)

asc*_*ler 22

两个C风格的字符串可以具有相同的内容但位于不同的地址.这map比较了指针,而不是内容.

转换成本的成本std::map<std::string, int>可能不如您想象的那么多.

但如果您确实需要使用const char*地图键,请尝试:

#include <functional>
#include <cstring>
struct StrCompare : public std::binary_function<const char*, const char*, bool> {
public:
    bool operator() (const char* str1, const char* str2) const
    { return std::strcmp(str1, str2) < 0; }
};

typedef std::map<const char*, int, StrCompare> NameMap;
NameMap g_PlayerNames;
Run Code Online (Sandbox Code Playgroud)


Dan*_*nas 8

您正在使用a比较使用char *字符串.他们不一样.

A char *是指向char的指针.最终,它是一个整数类型,其值被解释为a的有效地址char.

字符串是一个字符串.

容器正常工作,但作为对的容器,其中键是a char *,值是a int.


sbi*_*sbi 8

你可以使用它std::map<const char*, int>,但不能使用非const指针(注意const为键添加的),因为当地图将它们称为键时,你不能更改这些字符串.(虽然地图通过制作它们来保护它的键const,但这只会使指针,而不是指向它的字符串.)

但你为什么不简单地使用std::map<std::string, int>?它开箱即用,没有头痛.