背景。
我曾经写过C ++代码,现在我又重新开始了。我正在阅读一些涵盖c ++ 11(及更高版本)功能的书。堆栈溢出也有许多复杂的答案,但我只需要一个简单的答案。
在处理指针时,我通常遵循着名的三个规则,但是现在我看到了新的 move语义,因此该规则已重命名为五个规则。在线阅读我已经看到C ++进化了,现在也有了复制省略。我现在有很多新概念。看这个:
struct Test {};
auto getNewTest() { return Test(); }
auto x = getNewTest();
在这种情况下(假设启用了复制删除功能),唯一出现的复制应该是当我将值分配给x
(仅1个副本)时。相反,以前有2个副本:1个为返回值,1个为赋值x。
到目前为止还不错,但是有了移动语义,我可以达到相同的目的(如果我是对的)!假设Test已正确分配了移动操作;我可以这样称呼:
auto getNewTest() { return Test(); }
auto x = std::move(getNewTest());
问题
我了解到,当我必须摆脱旧变量时,移动是一件好事,而不是将其复制到新变量中,而是可以将其所有内容移动到新变量中。
碰巧我有一个像return SomeClass(1,2,3)
这样的语句,并且我想避免太多副本。 std :: move()是否做零份?因为复制省略避免1个复制(返回值),并且由于复制构造函数而仅执行1个复制。
我的猜测是,我使用std :: move()窃取了从函数创建的对象,因此我的副本为零。我对么?通常这可能是平庸的,但对我来说却花费了很多时间。
答案 0 :(得分:1)
您想得太多。编写代码后,
begin
for cur_r in (select ename, ssno, empno, sal from emp) loop
begin
insert into ok_data (ename, ssno, empno, sal)
values (cur_r.ename, cur_r.ssno, cur_r.empno, cur_r.sal);
exception
when others then
insert into failed_data (ename, ssno, empno, sal)
values (cur_r.ename, cur_r.ssno, cur_r.empno, cur_r.sal);
end;
end loop;
end;
实际上是在适当的位置构造auto x = getNewTest();
,这与您获得的效率差不多。
这种行为在C ++ 17中得到了保证,但实际上,这种行为已经存在了很长时间。
更多here。我不推荐cppreference太高,尽管它不是权威。