- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在此问题的评论和答案中: Virtual function compiler optimization c++有人认为循环中的虚函数调用不能被去虚拟化,因为虚函数可能会使用放置新的另一个对象替换 this
,例如:
void A::foo() { // virtual
static_assert(sizeof(A) == sizeof(Derived));
new(this) Derived;
}
示例来自 LLVM blog article about devirtualization
现在我的问题是:标准是否允许这样做?
我可以在 cppreference 上找到这个关于存储重用:(强调我的)
A program is not required to call the destructor of an object to end its lifetime if the object is trivially-destructible or if the program does not rely on the side effects of the destructor. However, if a program ends the lifetime of an non-trivial object, it must ensure that a new object of the same type is constructed in-place (e.g. via placement new) before the destructor may be called implicitly
如果新对象必须具有相同的类型,则它必须具有相同的虚函数。所以不可能有不同的虚函数,因此去虚化是可以接受的。
还是我误解了什么?
最佳答案
你提供的报价说:
If a program ends the lifetime of an non-trivial object, it must ensure that a new object of the same type is constructed in-place (e.g. via placement new) before the destructor may be called implicitly
此声明的意图与您正在做的事情有些不同。该语句的意思是说,当您在不破坏其名称的情况下销毁对象时,某些东西仍然引用具有原始类型的存储,您需要在那里构造一个新对象,以便在发生隐式销毁时,有一个有效的对象摧毁。例如,如果您有一个自动(“堆栈”)变量,并且您调用它的析构函数 - 您需要在该变量超出范围时调用析构函数之前在那里构造一个新实例。
整个语句,尤其是它的“相同类型”子句,与您正在讨论的主题无关,即是否允许您构造具有相同存储要求的不同多态类型一个旧的地方。我不知道为什么你不应该被允许这样做。
现在,话虽如此,您链接到的问题正在做一些不同的事情:它在循环中使用隐式 this
调用函数,问题是编译器是否可以假定 vptr for this
在该循环中不会改变。我相信编译器可以(并且 clang -fstrict-vtable-pointers
确实)假设这一点,因为 this
只有在放置 之后类型相同时才有效新的
。
因此,虽然您提供的标准中的引用与此问题无关,但最终结果是优化器似乎可以在假设 的类型的情况下对循环中进行的函数调用进行去虚拟化*this
(或其 vptr)不能更改。存储在某个地址的对象类型(及其 vptr)可以更改,但如果更改,旧的 this
将不再有效。
关于c++ - 是否允许用其他类型替换 `this`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50233168/
我想对一个字符串执行搜索和替换,比如 password。 正如您从问题中了解到的那样,替换后的字符串应变为 sdvvzrug。 但不幸的是,下面的代码输出bbbbcaab: $search = ran
我正在使用 futurize --stage2它应用了许多源代码转换以使代码 python2 和 python3 兼容。其中一个修复是所有分区 a/b 都替换为 old_div(a/b),我想避免这种
我正在使用 RStudio,但我在控制台上的输出被截断了。我找不到如何停止截断(我尝试搜索 ?options 以及在谷歌上搜索的时间比我想承认的要长)。 编辑:我向大家道歉!我最初的长名称为“This
我有一个 fragment 堆栈,我在其中使用替换和相加。添加或替换我的 fragment 的代码(在我的 Activity 中)如下 private fun addFragment(fragment
我在一个数组中插入了一些字符串,但在我这样做之前,我想按照主题所说的去做。只用 %20 替换空格,我这样做: Name.push(linkText.replace(" ", "%20")); 但是我如
我正在尝试编译和测试我在网上看到的代码 Expanding an IP add 。但是,当我尝试编译它时,我收到有关 StringBuilder 替换方法的错误。它说: IPadd.java:52:
我正在尝试使用 dplyr 的最新功能重写我的部分代码,方法是将 data.frame() 替换为 data_frame() 和 cbind() 与 bind_cols(): library(rgeo
我最近偶然发现了 replace()和 "[ x.tst s.tst s.tst [,1] [,2] [,3] [1,] 0 0 0
我一直想知道,如何在给定的参数内进行替换。 如果你有这样的一行: 123,Hello,World,(I am, here), unknown 你想更换 World与 Foobar那么这是一个简单的任务
如何转义字符串中的双引号?例如, input: "Nobody" output: \"Nobody\" 我尝试过这样的操作,但不起作用: String name = "Nobody"; name.r
我正在做类似的事情: SQL sql sQl SqL var ps = document.getElementsByTagName('p'); for(var i = 0; i 但它不会替换文本。
我正在尝试用 \" 替换所有 " 并用 JSON 解析字符串,但浏览器抛出错误 SyntaxError: JSON Parse error: Unrecognized token '\'. 下面是代码
大家好,在这里挣扎...... 是否可以将第一个正斜杠之间的任何内容替换为“”,但保留其余部分? 例如var 将是 string "/anything-here-this-needs-to-be-re
在下面的代码中,JavaScript 替换函数中的 alert(a) 将提醒匹配的字符串,在本例中,将是 {name} 和 {place}。 这按照文档 javascript docs 的描述工作,即
+-----------------------------+ | tables | +-------------------
我正在尝试用\"替换包含 "的字符串,下面是我尝试过的程序 String s="\"/test /string\""; s = s.replaceAll("\"", "\\\"");
var text = "a's ..a's ...\"... "; text = convert(text); function convert( text ) { var n = text
我正在尝试使用 JavaScript 中的替换函数,但有一个问题。 strNewDdlVolCannRegion = strNewDdlVolCannRegion.replace(/_existing
好吧,首先我对我的上一篇文章感到非常抱歉,但我真的需要帮助,我会把我真正想要的东西放在一个更清晰的代码中。我不擅长 javascript,所以希望你能帮助我。
我正在写一张纸条,遇到了障碍。可能有更有效的方法来执行此操作,但我对 Python 还很陌生。我正在尝试创建用户生成的 IP 地址列表。我正在使用 print 来查看生成的值是否正确。当我运行此代码时
我是一名优秀的程序员,十分优秀!