百科问答小站 logo
百科问答小站 font logo



为什么 C++ std::map::operator[] 不提供 const 版本? 第1页

  

user avatar   zhuangyan-stone 网友的相关建议: 
      

是基于这样的编码便利考虑的啦:

           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++,但苦于无人引领正路的同学?私我。




  

相关话题

  C++对一个map不断insert delete元素(多任务中的一个任务),是否存在内存碎片问题? 
  「C++ 早就过时了,大部分写工程不用 C++,学习这个语言只是为了竞赛」的观点是否正确? 
  如何看待清华大学自动化系2020年大一c++大作业是写一个功能更强大的雨课堂(雷课堂)? 
  C/C++有什么库可以完成命令行参数解析? 
  请问#define PI 3.1416比float pi=3.1416有什么优势呢? 
  C++如何返回未知类型的空引用? 
  C 语言float和double哪个算得快? 
  C++如何返回未知类型的空引用? 
  C++为何不允许在函数中直接传递数组? 
  为什么很多大牛在写题的时候要加一堆宏? 

前一个讨论
Linux 发行版中哪个包管理器更强?
下一个讨论
有没有仅由中子构成的原子核?





© 2025-02-03 - tinynew.org. All Rights Reserved.
© 2025-02-03 - tinynew.org. 保留所有权利