问题标签 [design-rationale]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 如果键不存在,为什么 std::map operator[] 会创建一个对象?
我很确定我已经在某个地方看到了这个问题(comp.lang.c++?谷歌似乎也没有在那里找到它)但是在这里快速搜索似乎没有找到它,所以它是:
如果键不存在,为什么 std::map operator[] 会创建一个对象?我不知道,但对我来说,如果你与大多数其他 operator[](如 std::vector)相比,这似乎违反直觉,如果你使用它,你必须确保索引存在。我想知道在 std::map 中实现这种行为的理由是什么。就像我说的那样,当使用无效键访问时,更像是向量中的索引和崩溃(我猜是未定义的行为)不是更直观吗?
看到答案后细化我的问题:
好的,到目前为止,我得到了很多答案,说它基本上很便宜,所以为什么不或类似的东西。我完全同意这一点,但为什么不为此使用专用函数(我认为其中一条评论说在 java 中没有 operator[] 并且该函数称为 put)?我的观点是为什么 map operator[] 不像矢量那样工作?如果我在向量的超出范围索引上使用 operator[],即使它很便宜,我也不希望它插入一个元素,因为这可能意味着我的代码中有错误。我的观点是为什么它与地图不一样。我的意思是,对我来说,在地图上使用 operator[] 意味着:我知道这个密钥已经存在(无论出于何种原因,我只是插入了它,我在某处有冗余,无论如何)。我认为这样会更直观。
那就是说使用 operator[] 执行当前行为有什么好处(仅为此,我同意应该存在具有当前行为的函数,而不是 operator[])?也许这样可以提供更清晰的代码?我不知道。
另一个答案是它已经以这种方式存在,所以为什么不保留它,但是,可能当他们(stl 之前的那些)选择以这种方式实现它时,他们发现它提供了优势或什么?所以我的问题基本上是:为什么选择以这种方式实现它,这意味着与其他 operator[] 有点缺乏一致性。它有什么好处?
谢谢
delphi - Delphi:什么是Application.Handle?
是什么TApplication.Handle
?
- 它从何而来?
- 它为什么存在?
- 最重要的是:为什么所有表单都将其作为父窗口句柄?
德尔福帮助说:
TApplication.Handle
提供对应用程序主窗体(窗口)的窗口句柄的访问。
描述
在调用需要父窗口句柄的 Windows API 函数时使用句柄。例如,显示其自己的顶级弹出窗口的 DLL 需要一个父窗口来在应用程序中显示其窗口。使用 Handle 属性使此类窗口成为应用程序的一部分,以便它们与应用程序一起最小化、恢复、启用和禁用。
如果我专注于“应用程序主窗体的窗口句柄”一词,并且我认为它是指应用程序主窗体的窗口句柄,那么我可以比较:
- “应用程序主窗体的窗口句柄”,带有
MainForm
的窗口句柄Application
但它们不一样:
那么是什么Application.Handle
?
- 它从何而来?
- 它是什么 Windows® 窗口句柄?
- 如果是
Application
's的 Windows® 窗口句柄MainForm
,那么它们为什么不匹配? - 如果不是
Application
's的窗口句柄MainForm
,那是什么? - 更重要的是:为什么它是每个表单的最终
父所有者? 最重要的是:如果我尝试让表单成为无父无主的表单(因此它可以出现在任务栏上),或者尝试使用IProgressDialog之类的东西,为什么一切都会变得混乱?
我真正要问的是:使Application.Handle存在的设计原理是什么?如果我能理解为什么,那么应该如何变得显而易见。
通过二十个问题的游戏更新理解:
在谈到通过设置其所有者使窗口出现在任务栏上的解决方案时null
,彼得·弗莱德在 2000 年说:
这可能会导致从辅助形式显示的模态形式出现一些问题。
如果用户在模态表单打开时从应用程序切换,然后返回显示它的表单,则模态表单可能会隐藏在表单下方。可以通过确保模态表单是父级来解决这个问题[原文如此;他的意思是拥有] 以显示它的形式(
params.WndParent
如上使用)
Dialogs
但这对于来自单元和异常的标准对话框是不可能的,这需要更多的努力才能让它们正常工作(基本上处理Application.OnActivate
,寻找以Application via为父级的模态表单GetLastActivePopup
并将它们带到 Z-order via 的顶部SetWindowPos
) .
- 为什么模态表单最终会卡在其他表单后面?
- 什么机制通常将模态形式带到前面,为什么它在这里不起作用?
- Windows® 负责显示堆叠的窗口。Windows® 没有显示正确的窗口出了什么问题?
他还谈到了使用新的 Windows 扩展样式,该样式通过添加扩展样式来强制窗口出现在任务栏上(当使其不拥有的正常规则不足、不切实际或不受欢迎时)WS_EX_APPWINDOW
:
但随后他警告说:
如果您在另一个应用程序处于活动状态时单击辅助表单任务栏按钮,这仍会将所有应用程序表单置于前面。如果你不希望有选项
当表单的所有者静止时,谁将所有表单带到最前面Application.Handle
。应用程序是这样做的吗?为什么要这样做?与其这样做,不应该这样做吗?不这样做有什么缺点?我看到了这样做的缺点(系统菜单无法正常工作,任务栏按钮缩略图不准确,Windows® shell 无法最小化窗口。
在另一篇处理 . 的帖子中Application
,Mike Edenfield 说父窗口向其他窗口发送它们的最小化、最大化和恢复消息:
这将为您的表单添加任务栏按钮,但还有一些其他小细节需要处理。最明显的是,您的表单仍然会收到发送到父表单(应用程序的主表单)的最小化/最大化。为了避免这种情况,您可以通过添加如下行来为 WM_SYSCOMMAND 安装消息处理程序:
请注意,此处理程序以您希望独立于应用程序其余部分的行为的PARENT形式出现,以避免传递最小化消息。您可以为 SC_MAXIMIZE、SC_RESTORE 等添加类似的 > 代码。
为什么我的 Windows® 窗口的最小化/最大化/恢复消息没有进入我的窗口?这是因为 Windows® 将发往窗口的消息发送给了窗口的所有者吗?在这种情况下,Delphi 应用程序中的所有表单都是“拥有”的Application
?这是否意味着使所有者为空:
将删除Application
它的窗口句柄干扰我的表单,Windows 应该再次向我发送我的最小化/最大化/恢复消息?
也许如果我们现在比较和对比一个“正常”的 Windows 应用程序做事,与 Borland 最初设计 Delphi 应用程序做事的方式 - 关于这个Application
对象和它的主循环。
- 对象解决的是什么解决方案
Application
? - 更高版本的 Delphi 进行了哪些更改以使这些相同的问题不存在?
- Delphi 后期版本中的更改是否没有引入其他问题,最初的应用程序设计如此努力地解决?
- 那些较新的应用程序如何在没有应用程序干扰的情况下仍然运行?
显然,Borland 意识到了他们最初设计中的缺陷。他们最初的设计是什么,它解决了什么问题,缺陷是什么,重新设计是什么,它是如何解决问题的?
c++ - 为什么标准库有find和find_if?
不能find_if
只是超载find
吗?朋友也是这样的std::binary_search
。。。
c++ - 为什么不允许非类型参数中的部分特化使用嵌套模板参数
我有这个代码
也就是说,对于N
能被 整除的数字,5
编译器应该使用偏特化。但是编译器不会接受这种部分特化,因为标准要求它拒绝这样的代码,其中部分特化的非类型参数引用参数而不是简单的参数(例如,A<N, N>
将是有效的)。但是这样做的原因是什么?
请注意,我可以简单地将我的代码更改为更冗长的示例,并且它是有效的
这很好,因为它不再是非类型参数。但是规范禁止更直接的部分专业化的原因是什么?
c++ - 为什么不 std::set::erase 采用 const_iterator?
看来,根据 ISO 14882 2003(又名 C++ 的神圣标准)std::set<K, C, A>::erase
将iterator
其作为参数(不是 a const_iterator
)
从 23.3.3 [2]
void erase(iterator position);
还可能值得注意的是,在我的 VS2008 附带的 STL 实现中,const_iterator
当我尝试使用另一个编译器编译我的代码时,erase 会导致令人不快的惊喜。现在,由于我的版本采用 a const_iterator
,因此可以使用 a 来实现擦除const_iterator
(好像它不是不言而喻的)。
我想标准委员会已经考虑了一些实现(或手头现有的实现),这需要擦除来获取iterator
.
- 如果您同意这种情况,您能否描述一个
set::erase
需要修改将要删除的元素的实现(我不能)。 - 如果你不同意,请告诉我为什么他们会做出这个决定?我的意思是,擦除一个元素只是指针的一些重新排列!
编辑
我突然想到,即使在迭代器的情况下,您也无法修改集合中的元素。但问题仍然存在——为什么不使用 const_iterator,尤其是如果它们在某种意义上是等价的
java - 为什么不能在重写方法中放宽参数类型?
此代码无效:
因为 everyString
显然是 an ,Object
所以我希望这段代码非常好:任何依赖于在实际使用.foo()
String
foo()
Object
但是,似乎方法签名必须与它们覆盖的方法的签名相同。为什么?
c++ - Why do data() and c_str() return char const*, while operator[] returns char&?
Why do std::string::data
and std::string::c_str()
return pointers to const chars, while std::string::operator[]
returns references to mutable chars?
Why don’t std::string::data()
and std::string::c_str()
return char*
, or why doesn’t std::string::operator[]
return char const&
?
What is the rationale behind this?