提问人:DoehJohn 提问时间:6/3/2020 最后编辑:DoehJohn 更新时间:6/3/2020 访问量:54
使用移动语义:右值引用作为方法参数
Using move semantics: rvalue reference as a method parameter
问:
我想仔细检查一下我对移动语义的理解。我的推理中是否遗漏了什么:
#include <iostream>
using std::cout;
struct A
{
A() {cout<<"Constructor\n";}
~A() {cout<<"Desctuctor\n";}
A(const A&) {cout<<"Copy Constructor\n";}
A(A&&) noexcept {cout<<"Move Constructor\n";}
int x{1};
};
int f1(A a)
{
cout<<"f1(A a)\n";
return a.x;
}
int f2 (A&& a)
{
cout<<"f2 (A&& a)\n";
return a.x;
}
int main()
{
A a1, a2;
f1(std::move(a1));
f2(std::move(a2));
}
输出:
Constructor
Constructor
Move Constructor
f1(A a)
Desctuctor
f2 (A&& a)
Desctuctor
Desctuctor
从我所看到的,我没有创建任何额外的副本,甚至是“轻量级”移动副本,这很酷。
所以我现在的理解是,如果我要使用移动语义,我最好总是编写函数/方法签名来接受 r 值,以避免任何不必要的副本。还是我错过了其他东西?f2()
答:
2赞
xaxxon
6/3/2020
#1
你几乎总是最好只接受你要按值保留的输入(除了奇数类型,它们的移动成本非常高)。
它保持相同的性能级别(在常见方案中),并使代码非常易于理解。它还非常清楚地表明您的代码保留了该值(因为它可以保证被移出),因为右值引用不会强制执行该值。
如您所见,删除 print 语句时,示例的计时和生成的代码是相同的:http://quick-bench.com/ADU4fzd0ISk0UrLboVhC-Pd7RmI
评论
0赞
DoehJohn
6/3/2020
哇,尽管一个调用移动构造函数,而另一个非汇编程序代码是相同的,但这怎么可能?
0赞
xaxxon
6/3/2020
@DoehJohn它没有调用移动构造函数 - 这就是原因。en.cppreference.com/w/cpp/language/copy_elision verywellmind.com/....
评论
f1()
f2()
void
return
main()
int
#include