问题标签 [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 投票
2 回答
129 浏览

c++11 - RVO 是否需要移动构造函数/赋值才能在 C++11 中启动?

例如:

在接受的答案https://stackoverflow.com/a/14623480/1423254中,

复制省略和 RVO 是否仍然适用于没有移动构造函数的类?

是的,RVO 仍然起作用。实际上,编译器应该选择:RVO(如果可能)

在接受的答案https://stackoverflow.com/a/38043447/1423254中,

在非保证复制省略规则下,这将创建一个临时,然后从该临时移动到函数的返回值。该移动操作可能会被省略,但即使从未使用过,T 仍必须具有可访问的移动构造函数。

关键是我认为 RVO 和“左值移动”(或如何调用它们)是 2 个完全独立的操作,但我的同事告诉我,要启动 RVO,返回的类需要一个移动构造函数。所以我检查了互联网和SO,显然,无法快速找到信息......

0 投票
1 回答
112 浏览

c++ - NRVO 在正文中抛出异常是否有效?

我希望了解 NRVO 在 C++ 中的局限性。具有初始命名声明和单个返回的函数是否会针对 NRVO 和 elide 进行优化T val,即使该函数myFunc()具有抛出潜力?

0 投票
1 回答
53 浏览

gcc - 为什么在通过静态方法初始化时允许私有移动构造函数?

简化的代码片段是:

另请参阅我的实时示例(显示不同编译器的行为)。

最后,我想知道为什么auto a = A::create();使用较新的编译器 [gcc >= 7.1] 编译没有错误(C++17 标准的哪一部分与这里相关?),因为:

  1. 我们有一个不可复制的成员NonCopyable n;,因此默认的复制构造函数格式不正确。
  2. 这是一个 NRVO,因为A a; return a;标准不保证复制省略。
  3. 移动构造函数A(A&&)被标记为私有。
  4. 优化已关闭-O0以进行测试。

我的怀疑是编译器正在“验证”移动构造函数return a;;因为这是它的成员函数,A所以它通过了验证。即使怀疑是正确的,我也不确定这是否符合标准。

0 投票
1 回答
39 浏览

c++ - can't find a way to make garanteed return value optimization work

Why the clang says call to deleted constructor of 'Block<Tuple>::Self' (aka 'Block<Tuple>') in the call of Block<Tuple>::a1() when I delete the move constructor?

c++17 clang version 9.0.0 (tags/RELEASE_900/final) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin

From what I've readed, I could have garanteed rvo if I deleted the copy and move constructors. The compiler would complain in situations where he could not do rvo and the code would not compile. For instance, when I delete the copy constructor and define the move one with just throwing an error, he actually optimizes the calling of a1, since I got no errors. But when I delete the move constructor, the code does not even compile.

0 投票
1 回答
643 浏览

c++ - 使用 std::optional 时的命名返回值优化

我最近发现std::optional了一种提高代码清晰度的方法,特别是对于函数的返回值。但是,我对它对性能的影响有疑问。更具体地说,我想知道是否可以编写类似于下面的代码,以允许编译器应用命名返回值优化。

0 投票
1 回答
100 浏览

c++ - 如何对运算符返回值强制执行 RVO?

如何在最后 3 个运算符中强制执行 RVO:

程序运行输出:

或者std::move在最后三个运算符中显式使用时:

我不想在运算符中复制,如下所示:

到目前为止,我想出的唯一方法是从操作员那里返回一个引用,但这显然会导致一个悬空引用。

我用新鲜的 g++ 在 c++14 和 c++17 中编译。

更新

我知道在不违反规则的情况下,不可能强制编译器做我想做的事。
但是编译器在本地优化右值的 ptevents 是什么?我想它可以在第一次添加期间创建一个右值,在下一次添加中修改该右值,然后分配给结果变量。

0 投票
2 回答
753 浏览

c++ - 如何确保执行 RVO 而不是复制?

在许多情况下,我想创建一个新的数据实例并将其返回给 API 调用者。

我了解到unique_ptr/shared_ptr可用于工厂模式(例如,工厂模式 using unique_ptr in c++

同时,我了解到返回值优化 (RVO) 在许多编译器中都是可能的(例如,Efficient way to return a std::vector in c++)。

我更喜欢 RVO,因为它更容易使用没有包装的返回值unique_ptr并且更容易阅读代码,但是,由于 RVO 没有保证,我不想意外牺牲性能并且必须使用unique_ptr来确保返回值是moved而不是复制。

是否有任何方法可以明确指定要移动的返回值,以便如果 RVO 可能它不会抱怨任何事情,或者如果 RVO 不可能它会触发一些编译器警告?如果这是可能的,我可以安全地摆脱在这种情况下返回 unique_ptr 。

我正在使用 C++17,需要在 macOS 上支持 Apple Clang 11.0,在 Linux 上支持 g++ 9。

编辑:

我仍在学习 C++,并且在发布此问题时没有区分 RVO(返回值优化)和 NRVO(命名返回值优化)。在我看来,NRVO 在工厂方法等模式中更常见和有用,例如:

我正在寻找类似的东西return std::move_only(returned_value),如果这个值不能移动(而不是复制移动),它会给我一个编译器警告。也许我应该将我的问题重新表述为:如果不能保证 NRVO,为什么在这个问题中“按值返回”仍然是推荐的方式(在 c++ 中返回 std::vector 的有效方式),答案不应该是“这取决于”您的功能实现以及您是否可以接受意外的性能成本?

0 投票
2 回答
222 浏览

c++ - 复制省略(NRVO)可以删除复制和移动构造函数吗?

cppreference中据说

当操作数是与函数返回类型相同的类类型(忽略 cv 限定)的纯右值时,复制/移动构造函数不需要在 return 语句中出现或可访问:

我是否理解这一点,并且为了使上述示例正常工作,不可避免地至少有一个复制或移动构造函数?

我尝试的是以下内容:

为什么这段代码可以编译和工作?据我了解,getEmptyPlayer() 方法实际上需要调用复制构造函数以在返回时复制对象。由于编译器提高了效率,情况并非如此,而是复制省略(NRVO)开始转向并直接在应该存在的位置构造对象并且不进行复制。尽管如此,cppreference(见上文)表示需要存在可访问或现有的复制/移动构造函数。那么这里发生了什么?

先感谢您!

0 投票
1 回答
53 浏览

c++ - C++ 中的移动和复制构造函数

请看上面的代码为什么“studant c3=c2.maximum()”和“studant c4=create()”没有调用复制或移动构造函数。请解释一下。

0 投票
2 回答
1677 浏览

c++ - 如何避免NRVO的“悲观行动”警告?

g++ -Wall z.cpp给出如下警告:

我知道如果我更改return std::move(s);return s;,警告将被避免。但是,根据C++ 标准NRVO在这种情况下,不能保证。如果我写return s;,我不确定是否NRVO会被执行。

如何缓解不确定感?