C++STL映射无法识别密钥



我有这段代码,CBString只是我用来处理的一个字符串类

  char * scrummyconfigure::dosub(strtype input)
  {
    CBString tstring;
    tstring = input;
    uint begin;
    uint end;
    begin = tstring.findchr('$');
    end = tstring.findchr('}',begin);        
    CBString k = tstring.midstr(begin+2,end-2); // this is BASE
    strtype vname = (strtype) ((const unsigned char*)k);
    strtype bvar = (strtype) "BASE";
    assert(strcmp(bvar,vname) == 0); // this never fails
    // theconf is just a struct with the map subvars
    // subvars is a map<const char *, const char *>
    out(theconf->subvars[bvar]); // always comes up with the value
    out(theconf->subvars[vname]); // always empty
    uint size = end - begin;
    tstring.remove(begin, size);
    return (const char *)tstring; // it's OKAY! it's got an overload that does things correctly
    //inline operator const char* () const { return (const char *)data; } <-- this is how it is declared in the header of the library
  }

为什么strcmp总是说字符串是相同的,但只有我声明为bvar的变量返回任何内容?

我假设strtype以以下方式定义:

typedef char * strtype

您的问题是,您假设vname和bvar具有相同的值,而实际上,它们具有不同的值,每个值都指向包含相同数据的内存块。

std::map愚蠢地将它们与==进行比较,我敢打赌你会发现,如果你将它们与=进行比较,你会得到false,正如预期的那样。你为什么不使用std::string类?

编辑:我改写了你的方法,使其不那么可怕:

// implied using namespace std;
string ScrummyConfigure::removeVariableOrSomething(string tstring)
{
    uint begin; // I'll assume uint is a typedef to unsigned int
    uint end;
    begin = tstring.find('$', 0);
    end = tstring.find('}', begin);        
    string vname = tstring.substr(begin + 2, end - 2); // this is supposedly BASE
    assert(vname == "BASE"); // this should be true if vname actually is BASE
    out(this->conf->subvars[bvar]);  // wherever theconf used to be, its now a member
    out(this->conf->subvars[vname]); // of ScrummyConfigure and its been renamed to conf
    uint size = end - begin;
    tstring.erase(begin, size);
    return tstring; // no casting necessary
}

//subvars是map<const char *, const char *>

这个映射的关键字不是字符串,而是内存地址。相应的检查将是

assert( bvar == vname);

这可能会失败。您需要将键类型更改为字符串类(std::stringCBString)才能有意义地使用映射。

字符串相同并不意味着std::map会将它们视为相同的键。这取决于std::map使用的Compare类,该类默认为less<KeyType>,其结果与应用小于运算符相同。

您可以定义一个定义operator()的类来对strtype进行正确的比较,并在定义std::map时将其作为第三个模板参数传递。或者,按照建议,使用std::string作为strtype。

最新更新