【问题标题】:std::wstring not working with the [] operator of std::map<const wchar_t*, const char*>std::wstring 不适用于 std::map<const wchar_t*, const char*> 的 [] 运算符
【发布时间】:2013-05-15 20:14:52
【问题描述】:

我有一个const std::map&lt;const wchar_t*, const char*&gt;,它位于全局命名空间中。它看起来像这样:

.h 文件

typedef std::map<const wchar_t*, const char*> ShaderMap;

const ShaderMap::value_type rawShaderData[] = {
    ShaderMap::value_type( L"BasicShader_Vertex", 
        "..."
    ),
);

const int ElementCount = 2; //Length of rawShaderData
extern ShaderMap ShaderProgramsMap;

.cpp 文件

ShaderMap ShaderProgramsMap = ShaderMap( rawShaderData, rawShaderData + ElementCount );

我正在尝试在我的代码中的其他地方访问它,如下所示:

std::wstring shaderKey = std::wstring( name + L"_Vertex" );
...
pShaderData = ShaderProgramsMap[shaderKey.c_str()];

使用调试器,shaderKey 是“BasicShader_vertex”,但 pShaderData 是 NULL。将std::wstring::c_str 的值与const wchar_t* 的值进行比较是有问题还是代码中的其他地方有问题?

【问题讨论】:

  • 任何理由使用 std::map 代替 std::map<:wstring std::string> ?
  • 哦,名字的类型是什么?

标签: c++ string map std


【解决方案1】:
std::wstring shaderKey1 = std::wstring( name + L"_Vertex" );
ShaderProgramsMap[shaderKey1.c_str()] = "Whatever";

std::wstring shaderKey2 = std::wstring( name + L"_Vertex" );
pShaderData = ShaderProgramsMap[shaderKey2.c_str()];

shaderKey1.c_str() 返回的指针与shaderKey2.c_str() 不同。它们是 2 个不同的字符串,它们都分配了自己的数据并为您提供了指向该分配的指针。它们碰巧存储了相同的数据,但您只查看指针。如果要按字符串搜索和排序,请将键设为std::wstring,而不是const wchar_t*。同样,该值也很可能是std::string,而不是const char*,但我会让你决定。

您原来方法的另一个问题是shaderKey.c_str() 返回的指针将在shaderKey 超出范围后立即悬空。

【讨论】:

  • 或者保留map&lt;wchar_t const*, wchar_t const*&gt;,使用自定义比较器(使用例如strcmp)并准备UB,因为悬空指针。
  • @Dyp:如果地图是使用字符串初始化的,正如问题所暗示的,那么指针就不会悬空。
  • @BenVoigt 没错,我的意思是“如果 all 映射键 always 指向静态存储持续时间的对象”-> 错误- 容易
【解决方案2】:

我在您的示例代码中实际上没有看到 std::map -- 我看到 std::map::value_type 元素的数组(即 const char*)。

所以, const ShaderMap::value_type ShaderProgramsMap[] = { ... };

实际上是: std::pair&lt;wchar_t const* const, char const*&gt; const ShaderProgramsMap[] = { ... }

而且, pShaderData = ShaderProgramsMap[shaderKey.c_str()];

其实是:

int nArrayIndex = int(shaderKey.c_str());
pShaderData = ShaderProgramsMap[nArrayIndex]; // actually an array, not a map

【讨论】:

  • 你对问题中的代码提出了一个很好的观点......但你指出的问题应该是导致编译错误——没有从const char* 到 int 的隐式转换。
  • 是的——戴夫的回答可能就是真正的问题,那么
  • 我居然抄错了代码,发的时候没注意!抱歉,我用正确的代码更新了它。
猜你喜欢
  • 2021-03-21
  • 2018-08-23
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 2020-06-26
  • 1970-01-01
相关资源
最近更新 更多