Elm*_*der 1 c++ move std c++11
我一次又一次听到这std::move(t)
或多或少只是一种奇特的说法static_cast<T&&>(t)
,不会产生任何指示。当我现在std::move
为了更好地理解移动语义而使用 godbolt 时,我发现它确实(或至少可能)生成指令。在这个例子中
#include <iostream>
using namespace std;
struct S {
S() { cout << "default ctor" << endl; }
S(S&& s) {
i = s.i;
s.i = 0;
cout << "move ctor" << endl;
}
int i;
};
void foo(S s) { cout << "Foo called with " << s.i << endl; }
int main() {
S s;
foo(static_cast<S&&>(s));
foo(std::move(s));
}
Run Code Online (Sandbox Code Playgroud)
foo
导致以下汇编输出的调用
; ... snip ...
lea rdi, [rbp - 16]
lea rsi, [rbp - 8]
call S::S(S&&) [base object constructor]
lea rdi, [rbp - 16]
call foo(S)
lea rdi, [rbp - 8]
call std::remove_reference<S&>::type&& std::move<S&>(S&)
lea rdi, [rbp - 24]
mov rsi, rax
call S::S(S&&) [base object constructor]
lea rdi, [rbp - 24]
call foo(S)
; ... snip ...
std::remove_reference<S&>::type&& std::move<S&>(S&): # @std::remove_reference<S&>::type&& std::move<S&>(S&)
push rbp
mov rbp, rsp
mov qword ptr [rbp - 8], rdi
mov rax, qword ptr [rbp - 8]
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释一下吗?我不太明白这个std::remove_reference<S&>::type&& std::move<S&>(S&)
函数应该做什么,以及为什么与通常所说的有明显的缩减。
std::remove_reference<S&>::type&& std::move<S&>(S&)
Josuttis 在他的 C++ 移动语义中解释了这一点。
基本上它的作用与类型特征类似,static_cast<T&&>
但具有类型特征的手段。它允许传入任何值类别(因此,左值或右值引用),然后它会切断引用部分并应用于右值引用部分。至于额外的说明:任何优化器都应该内联这些调用。
关闭优化并foo
定义为void foo(const S& s);
减少噪音:
foo(static_cast<S&&>(s));
leaq -4(%rbp), %rax
movq %rax, %rdi
call foo(S const&)
Run Code Online (Sandbox Code Playgroud)
foo(std::move(s));
leaq -4(%rbp), %rax
movq %rax, %rdi
call std::remove_reference<S&>::type&& std::move<S&>(S&)
movq %rax, %rdi
Run Code Online (Sandbox Code Playgroud)
对于-O1
,两者的结果相同:
leaq 12(%rsp), %rdi
call foo(S const&)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
428 次 |
最近记录: |