问题标签 [nrvo]

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.

0 投票
4 回答
270 浏览

c++ - 对按值返回的值使用 const 引用

看下面的例子:

我知道 RVO 和 NRVO,但我认为为了做到这一点,我需要编写 bar 如下:

两个版本似乎都有效,我相信具有相同的性能。使用第一个版本(带有 const 参考)是否安全?

谢谢。

0 投票
2 回答
218 浏览

c++ - 哪种功能结构更好?

看下面的代码:

函数f2是返回对象的正常形式。NRVO可能适用,并且可以避免额外的复制构造函数调用。f1是使用右值引用的新形式。对于不支持 NRVO 但支持右值引用的系统,调用移动构造函数而不是复制构造函数,这在大多数情况下会被认为更好。

问题f1在于:在这种情况下是否有任何支持 NRVO 的编译器?毕竟,这似乎是未来更好的形式。

0 投票
5 回答
154 浏览

c++ - 在引入范围时额外调用复制 c-tor

原始代码

输出将0在支持命名返回值优化的优化编译器上。

当我将定义更改foo

我得到1作为输出,即复制 c-tor 被调用一次。可能的原因是什么?引入虚拟作用域会完全改变代码的行为。我错过了什么?

我在 g++ 编译器上对其进行了测试。这里有任何编译器人员可以以某种特定于实现的方式解释该场景吗?

编辑

我在 clang 上对其进行了测试,即使在第二种情况下,它也优化了对复制 c-tor 的调用。

Andrew Pinski(gcc 专家)证实这确实是 g++ 错过优化的一个案例。

0 投票
6 回答
2069 浏览

c++ - 返回值优化 - C++ - 析构函数调用

以下代码调用析构函数 4 次:

输出:

有人可以解释一下吗?我在想应该只有三个析构函数调用。

0 投票
6 回答
430 浏览

c++ - 当 RVO/NRVO 启动时,对象是否被复制?

我无法理解 RVO(和 NRVO)的定义,因为像这样的多个问题在我看来假设 RVO 省略了复制构造函数。现在根据 12.8.15

在这种情况下,实现将省略的复制操作的源和目标简单地视为引用同一对象的两种不同方式,并且该对象的销毁发生在两个对象本应被销毁的较晚时间优化。

看起来不是复制构造函数调用被省略,而是复制本身 - 只是对象首先在“复制”位置构造,因此没有“原始”对象,根本没有复制。因此,即使一个类有一个private复制构造函数,它也可以在 RVO 启动时从函数中返回,因为没有复制。

我做对了吗?是复制本身省略还是复制构造函数调用省略?当对象类具有私有复制构造函数时,是否应允许从函数返回对象?

0 投票
1 回答
427 浏览

c++ - (N)RVO 的完整示例

我一直在阅读有关 (N)RVO 的内容,并且想要一份完整的场景描述。我希望这个问题能帮助其他 C++ 学习者澄清他们的想法。

假设这种情况:

请暂时忽略 C++11 移动语义。

  • 如果不执行 (N)RVO,将执行多少个构造函数/赋值/析构函数?(请指出它们所指的对象)
  • 如果应用 (N)RVO,会发生什么变化?
  • 最后,假设std::string支持移动语义的 C++11 中的情况如何变化。
0 投票
4 回答
1312 浏览

c++ - 返回 std::pair 时会发生 RVO 吗?

一个函数需要向调用者返回两个值。最好的实施方式是什么?

选项1:

选项 1.1:

选项 2:

我知道 Option2 没有副本/移动,但看起来很难看。选项 1、1.1 中是否会发生任何复制/移动?让我们假设 U 和 V 是支持复制/移动操作的巨大对象。

问:理论上是否可以按照标准进行任何 RVO/NRVO 优化?如果是,是否已实现 gcc 或任何其他编译器?

0 投票
3 回答
1714 浏览

c++ - 如何在 msvc 中强制返回值优化

我在一个类中有一个函数,我希望编译器在......一直使用 NRVO......即使在调试模式下也是如此。对此有语用吗?

这是我的课程在“发布”模式下效果很好:

除非需要超过 _cbStack 字节,否则该类用于在堆栈上创建缓冲区。然后当它销毁时,如果它分配了任何内存,它就会释放内存。当与需要字符串缓冲区的 c 函数交互时,它很方便,并且您不确定最大大小。

无论如何,我试图编写一个可以返回 CBuffer 的函数,就像在这个测试中一样:

我指望 NRVO 让 foo() 快速。在发布模式下,它工作得很好。在调试模式下,它显然会失败,因为我的类中没有复制构造函数。我不想要复制构造函数,因为喜欢复制所有内容 50 次的开发人员将使用 CBuffer。(咆哮:这些家伙正在使用动态数组类创建一个包含 20 个字符的缓冲区以传递给 WideCharToMultiByte(),因为他们似乎忘记了您可以只在堆栈上分配一个字符数组。我不知道是否他们甚至知道堆栈是什么......)

我真的不想编写复制构造函数,以便代码在调试模式下工作!它变得庞大而复杂:

此编译指示不起作用:

有任何想法吗?

0 投票
1 回答
2109 浏览

c++ - C++ 编译器可以为 const 返回值执行 RVO 吗?

假设我有这个功能

编译器能否为 执行(命名)返回值优化t,即使s和的类型由于-ness 差异而t与 的返回类型不同?fooconst

(如果 C++03 和 C++11 的答案不同,那么我肯定有兴趣知道 C++03 的答案。)

0 投票
2 回答
119 浏览

c++ - 为什么下面的代码也会调用复制构造函数?

为什么当g_Fun()执行到时return temp它会调用复制构造函数?