百科问答小站 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++ 开源项目? 
  C++对比其他语言到底难在哪里?有人对C++异常推崇,除了性能优势,还有什么优点,怎么学好C++? 
  ”返回在函数内malloc的内存是安全的,但是容易造成问题,最好的做法是返回传入的指针。“怎么理解? 
  为什么 C++ std::map::operator[] 不提供 const 版本? 
  为什么 Go 和 Rust 常提供静态编译好的 Linux 程序,而 C 不行? 
  c#中虽然异步和多线程是两码事,但是是否异步微软提供的async函数内部还是多线程去实现的? 
  如果编译器遇到未定义行为把硬盘格式化了,需要负法律责任吗? 
  朋友自杀前把名字改成了nullptr,是什么意思? 
  如何格式化代码能够将类成员/函数的名字对齐? 
  LeetCode上 C++ 官方题解为什么有很多没有写delete,不会内存泄漏么?面试时也可以么? 

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





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