问题标签 [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.
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,显然,无法快速找到信息......
c++ - NRVO 在正文中抛出异常是否有效?
我希望了解 NRVO 在 C++ 中的局限性。具有初始命名声明和单个返回的函数是否会针对 NRVO 和 elide 进行优化T val
,即使该函数myFunc()
具有抛出潜力?
gcc - 为什么在通过静态方法初始化时允许私有移动构造函数?
简化的代码片段是:
另请参阅我的实时示例(显示不同编译器的行为)。
最后,我想知道为什么auto a = A::create();
使用较新的编译器 [gcc >= 7.1] 编译没有错误(C++17 标准的哪一部分与这里相关?),因为:
- 我们有一个不可复制的成员
NonCopyable n;
,因此默认的复制构造函数格式不正确。 - 这是一个 NRVO,因为
A a; return a;
标准不保证复制省略。 - 移动构造函数
A(A&&)
被标记为私有。 - 优化已关闭
-O0
以进行测试。
我的怀疑是编译器正在“验证”移动构造函数return a;
;因为这是它的成员函数,A
所以它通过了验证。即使怀疑是正确的,我也不确定这是否符合标准。
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.
c++ - 使用 std::optional 时的命名返回值优化
我最近发现std::optional
了一种提高代码清晰度的方法,特别是对于函数的返回值。但是,我对它对性能的影响有疑问。更具体地说,我想知道是否可以编写类似于下面的代码,以允许编译器应用命名返回值优化。
c++ - 如何对运算符返回值强制执行 RVO?
如何在最后 3 个运算符中强制执行 RVO:
程序运行输出:
或者std::move
在最后三个运算符中显式使用时:
我不想在运算符中复制,如下所示:
到目前为止,我想出的唯一方法是从操作员那里返回一个引用,但这显然会导致一个悬空引用。
我用新鲜的 g++ 在 c++14 和 c++17 中编译。
更新
我知道在不违反规则的情况下,不可能强制编译器做我想做的事。
但是编译器在本地优化右值的 ptevents 是什么?我想它可以在第一次添加期间创建一个右值,在下一次添加中修改该右值,然后分配给结果变量。
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
来确保返回值是move
d而不是复制。
是否有任何方法可以明确指定要移动的返回值,以便如果 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 的有效方式),答案不应该是“这取决于”您的功能实现以及您是否可以接受意外的性能成本?
c++ - 复制省略(NRVO)可以删除复制和移动构造函数吗?
在cppreference中据说
当操作数是与函数返回类型相同的类类型(忽略 cv 限定)的纯右值时,复制/移动构造函数不需要在 return 语句中出现或可访问:
我是否理解这一点,并且为了使上述示例正常工作,不可避免地至少有一个复制或移动构造函数?
我尝试的是以下内容:
为什么这段代码可以编译和工作?据我了解,getEmptyPlayer() 方法实际上需要调用复制构造函数以在返回时复制对象。由于编译器提高了效率,情况并非如此,而是复制省略(NRVO)开始转向并直接在应该存在的位置构造对象并且不进行复制。尽管如此,cppreference(见上文)表示需要存在可访问或现有的复制/移动构造函数。那么这里发生了什么?
先感谢您!
c++ - C++ 中的移动和复制构造函数
请看上面的代码为什么“studant c3=c2.maximum()”和“studant c4=create()”没有调用复制或移动构造函数。请解释一下。
c++ - 如何避免NRVO的“悲观行动”警告?
g++ -Wall z.cpp
给出如下警告:
我知道如果我更改return std::move(s);
为return s;
,警告将被避免。但是,根据C++ 标准,NRVO
在这种情况下,不能保证。如果我写return s;
,我不确定是否NRVO
会被执行。
如何缓解不确定感?