以下代碼在 Visual Studio 2019 msvc x64 中編譯時沒有警告:
class ThreadRunner {
public:
void start() {
m_thread = std::move(std::thread(&ThreadRunner::runInThread, this));
}
private:
void runInThread() {
for (int i = 0; i < 1000 * 1000; i ) {
std::cout << "i: " << i << "\n";
}
};
std::thread m_thread;
};
但是,如果我使用 x64-Clang 編譯相同的代碼,則會收到以下警告:
warning : moving a temporary object prevents copy elision [-Wpessimizing-move]
這是否意味著我應該寫:
m_thread = std::thread(&ThreadRunner::runInThread, this);
反而?并且編譯器會優化掉(“復制省略”)臨時變數?
msvc x64 也會復制省略臨時變數嗎?
我做了一個實驗:
struct B {
void f1() {
a = A(5);
}
void f2() {
A tmp = A(5);
a = tmp;
}
void f3() {
a = std::move(A(5));
}
void f4() {
A tmp = A(5);
a = std::move(tmp);
}
A a;
};
f1、f3 和 f4 產生對 A 成員函式的相同呼叫序列:
default ctor
ctor
move = operator
f2 產生另一個結果:
default ctor
ctor
= operator
uj5u.com熱心網友回復:
這是否意味著我應該寫:
m_thread = std::thread(&ThreadRunner::runInThread, this);反而?
是的,這意味著你應該擁有。std::thread(&ThreadRunner::runInThread, this)是一個純右值,并且通過將其轉換為 xvalue,您什么也得不到。
uj5u.com熱心網友回復:
兩個版本
m_thread = std::thread(&ThreadRunner::runInThread, this);
和
m_thread = std::move(std::thread(&ThreadRunner::runInThread, this));
行為相同。在這兩種情況下都不可能省略,因為這是對 的賦值,而不是初始化m_thread。必須構造臨時物件,然后在任一版本中都會對其進行移動分配。
不過,提示仍然是正確的,因為std::move在臨時性上要么根本沒有任何效果(如此處),要么如果在允許/強制復制省略的背景關系中使用,則防止省略,例如,如果這是初始化m_thread而不是分配給它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/416509.html
標籤:
