我一次又一次聽到這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));
}
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
有人可以向我解釋一下嗎?我不太明白這個std::remove_reference<S&>::type&& std::move<S&>(S&)函式應該做什么,以及為什么與通常所說的相比有這種明顯的收縮。
uj5u.com熱心網友回復:
至于std::remove_reference<S&>::type&& std::move<S&>(S&)
Josuttis 在他的 C 移動語意中解釋了這一點。
基本上它的作用與型別特征相似,static_cast<T&&>但具有型別特征。它允許傳入任何值類別(因此,無論是左值還是右值參考),然后它會切斷參考部分并應用于 rvalue-ref 之一。至于額外的說明:任何優化器都應該行內這些呼叫。
關閉優化并foo定義為void foo(const S& s);減少噪音:
foo(static_cast<S&&>(s));
leaq -4(%rbp), %rax
movq %rax, %rdi
call foo(S const&)
foo(std::move(s));
leaq -4(%rbp), %rax
movq %rax, %rdi
call std::remove_reference<S&>::type&& std::move<S&>(S&)
movq %rax, %rdi
使用-O1,兩者的結果相同:
leaq 12(%rsp), %rdi
call foo(S const&)
uj5u.com熱心網友回復:
您正在編譯沒有優化。因此,您可以準確地看到所寫的內容,而無需任何簡化或行內函式的嘗試。
生成的代碼大致相當于生成的代碼type&& foo(type& x) { return x; },即生成的代碼move。
研究在沒有開啟優化的情況下生成的裝配是徒勞的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/460428.html
