是基于这样的编码便利考虑的啦:
map<char const* const, char const*> zsk; zsk["爸爸的爸爸"] = "爷爷"; zsk["爸爸的妈妈"] = "奶奶"; zsk["我爱而不得的"] = "你";
你看,一开始 zsk(知识库) 是空的,接下来三行代码,是在用:
爸爸的爸爸 是 爷爷
爸爸的妈妈 是 奶奶
……
如此的符合直觉的方式,来为幼儿“知识库”(zsk) 这个字典添加 知识条目……
当然,这样做是有代价的——你说的情况就是代价的一种表现:[ ] 这个操作在这里,不能是只读的了——真实影响如下:
代价之一,当我们只是想检索(检索、检索)一条知识条目,而该条目恰好不存在时,知识库里会偷偷摸摸地添加一条内容是空白的知识条目:
std::cout << zsk["老婆的妈妈"] << std::endl;
知识字典里现在有了新条目“老婆的妈妈”,不管题主有没有老婆,反正在zsk这个字典里,现在存在:“老婆的妈妈” 和 空值(在本例中是可怕的空指针,上述那行代码,事实上已经为程序的后续执行,埋下了可怕的祸根!) 这样的对应关系。
代价之二,当然我们平常使用 [ ] 这个操作符的习惯不同,无论是原生的数组,还是 std::array, std::vector,当 找通过键(二者只能用整数)检索值时,它们发生这种找不到还强行读取后的反应,是臭名昭著的 未定义 行为。 std::map 突然把它变成 已定义确似乎很安全的行为,那感觉就像你女友突然对你温柔起来一样……往往更令人心中发毛。
解决办法,是用语义更清晰的 find 来处理:
C++20时,如果只是为了判断是否存在,还可以用 “contains”方法:
at() 成员 有只读的。因为没有人会这么写:
m.at("你值得读读的入门到入神的C++书籍") = "白话C++";
又长也不直观,所以没必要牺牲这么多来为它提供前述的便利。
如果一切可以重来的话,我有在想,这个行为是不是可以改进呢?
显然,关键在于 map 对象,自己能不能知道 自己在某个表达式里,自己是在被读取(右值),还是在被修改(左值)呢?如果能区分出来,那么 赋值仍然可以映射到一旦发现是新KEY,就直接添加;而读取呢,能不能返回一个C++17的里 optional<T> ???
为什么许多已经掌握其它语言的同学学习C++之后,整个人的档次都提升了,气质也变得更加有底蕴了?原因之一就在于用了C++,他从一个纯使用语言干活的民工,迅速被逼迫变为开始思考手中工具的设计的思想者。
所以,有没有想学C++,但苦于无人引领正路的同学?私我。