问题标签 [copy-elision]
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++ - 两步复制省略以在构造函数调用中捕获右值作为实例变量
我正在尝试获取rvalue
此类的一个实例:
x
进入这个类的实例变量:
像这样:
没有任何复制或移动。
根据这些参考资料,
- http://thbecker.net/articles/rvalue_references/section_01.html
- http://www.slideshare.net/oliora/hot-11-2-new-style-arguments-passing
还有很多关于 SO 的帖子(所以请在标记为重复之前阅读到最后),我应该依赖复制省略,如果我通过值传递应该满足其条件。请注意,需要两个复制省略,即:
constructor call -> constructor local variable -> instance variable
关闭复制省略时可以看到(使用 编译g++-4.8 -std=c++11 -fno-elide-constructors
):
所以有一个move
步骤和一个copy
步骤,如果我打开复制省略(用 编译),这两个步骤都应该消失g++-4.8 -std=c++11 -O3
:
糟了,还剩copy
一步!
我可以通过任何其他变体std::move()
或std::forward
传递为更好rvalue-reference
吗?
产生输出:
好的,我把copy
变成了move
,但这并不令人满意!
接下来,我尝试使实例变量x
成为引用X&
:
产生:
馊主意!我摆脱了move
但引用的rvalue
实例x
在我的座位下被破坏了,所以最后一行打印垃圾而不是5
. 两个注意事项:
g++-4.8
没有警告我任何事情,即使有-pedantic -Wall -Wextra
5
程序在编译时打印-O0
所以这个错误可能会在很长一段时间内被忽视!
那么,这是一个没有希望的案例吗?没有:
印刷:
真的吗?没有花哨的新C++11
功能,没有编译器自行决定的复制省略,只是普通的旧 FORTRAN66 样式的传递引用可以满足我的要求,并且可能会表现最好?
所以这是我的问题:
- 有什么办法可以让它工作
rvalues
吗?我错过了任何功能吗? - -reference
lvalue
版本真的是最好的,还是有隐藏的成本?X x(6)
? x
建造后生活会不会带来任何不便f
?- 我可以为使用对
lvalue
外部实例的引用支付数据局部性罚款吗?
c++ - 通过隐式转换返回时是否需要复制构造函数?
以下代码在 Visual C++ 2013 中编译良好,但在 GCC 或 Clang 下编译失败。
哪个是对的?
通过隐式转换返回对象时是否需要可访问的复制构造函数?
海合会:
铛:
c++ - std::vector 初始化元素的移动/复制构造函数
我有这段代码:
输出是我所期望的(用 编译g++ -std=c++11 --no-elide-constructors
,没有标志的相同输出)
现在而不是push_back
直接使用初始化向量v
作为
我不明白为什么我得到输出:
1) (没有--no-elide-constructors
)
2) (带--no-elide-constructors
)
在第一种情况下,为什么要调用复制 ctor?在第二种情况下,当编译器不执行省略时,我完全不知道为什么调用了 move ctor 两次。有任何想法吗?
c++ - 如何在 C++ Builder (Clang) 中禁用 RVO?
我正在使用 C++ Builder XE6,并且正在尝试使用移动构造函数进行一些测试,以将结果与复制构造函数进行比较。无论如何,即使在编译器设置中选中“禁用所有优化”,我的编译器也会强制执行 RVO 优化。是否有一些额外的参数需要发送到编译器?
c++ - 如何在没有 std::move 的情况下按值返回 unique_ptr?
在上面的代码中,该函数ptr()
返回一个p
. 当p
超出范围时,数据“3”应该被删除。但是代码如何在没有任何访问冲突的情况下工作?
c++ - 使用函数的返回值初始化对象时未调用复制构造函数
考虑以下代码:
上面代码的输出g++ file.cpp
是:
上面代码的输出g++ -fno-elide-constructors file.cpp
是:
我知道返回值优化。我的问题是省略了对复制构造函数的哪个调用(返回期间的临时对象或返回的对象被复制到 b)?
如果省略的复制构造函数是用于创建 b 的构造函数,那么 b 是如何创建的(因为在这种情况下也没有构造函数调用)?
如果我用第一种方法甚至第二种方法替换该行并进行编译,那么复制构造函数也被调用了 2 次A b = a.fun(c);
。a.fun(c)
那么,如果在上一段解释的情况下,临时对象的复制构造函数被省略了,那么为什么在这种情况下不省略呢?
c++ - 从重载的 + 运算符返回到重载的 = 运算符时未调用复制构造函数
考虑以下代码:
使用命令编译此程序时:g++ file.cpp
,输出为:
然后使用命令编译这个程序:g++ -fno-elide-constructors file.cpp
,输出是:
我的问题是:
在第一种情况下,为什么省略了两个复制构造函数?
还是省略了哪些复制构造函数?= 运算符或 + 运算符是否有不同的机制
编辑
我知道正确的赋值运算符或复制构造函数应该是什么样子。请回答为什么在上述情况下省略了两个复制构造函数而不是更正赋值运算符。
c++ - gcc 和 clang 在下面的代码片段中都省略了对 move 构造函数的调用。它是否正确?
在下面的代码中s
,类对象S
用于使用D
直接初始化来初始化类对象D d(s);
。转换函数 S::operator D() 用于将对象s
转换为 类型的临时对象D
。然后,gcc 和 clang 都省略了对 move 构造函数的显式调用D(&&)
,将这个临时对象移动到d
. 见活的例子。
我对这种省略的正确性提出质疑,理由如下:
- 这种情况在第 8.5/16 节 (N3337) 的第一个子要点中有所涉及,它没有提及省略。
如果初始化是直接初始化,或者如果是复制初始化,其中源类型的 cv 非限定版本与目标类相同或派生类,则考虑构造函数。枚举了适用的构造函数(13.3.1.3),并通过重载决议(13.3)选择最佳构造函数。调用如此选择的构造函数来初始化对象,使用初始化表达式或表达式列表作为其参数。如果没有构造函数适用,或者重载决议不明确,则初始化格式错误。
- 请注意,下一个子要点明确提到了省略的可能性。
- 对移动构造函数的调用是显式的。怎么可以省略呢?
c++ - 未调用模板类复制构造函数
我的复制构造函数没有被调用,我不确定为什么。这是我的代码:
输出只是“ctor”。看起来使用了默认的复制构造函数。如果我添加“显式”,则它不会编译,并给出错误:
我在这里做错了什么?
c++ - 基于for循环的范围内复制省略
我有以下代码:
我运行了这个程序并打印了:
我的问题是为什么要复印?调用时push_back(A())
为什么没有省略副本?在行for (A a: vec)
中为什么没有省略副本?
我正在使用以下命令进行编译:
sh-4.3# g++ -std=c++11 -O3 -o main *.cpp