百科问答小站 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++中要分为heap(堆)和stack(栈)? 
  大一学生,刚开始学习编程,但感觉自己并没有天赋怎么办? 
  为何void类型指针不能解引用,却可以参与强制类型转换? 
  相比其他语言,C、C++究竟快在哪里? 
  为什么C语言中计算机认为0是假的,其他数都是真的? 
  C++ make_tuple返回值类型,会有效率问题吗? 
  编程时怎么把函数当做变量使用? 
  Qt QTime的toString是如何实现的? 
  对同一个套接字,在两个线程中都对其调用recv函数,需要对其互斥保护吗? 
  指针数组初始化为 nullptr 和直接使用 memcpy 有什么区别? 

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





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