[英]Why is move necessary with emplace_back in this example?
當使用選項1或選項2下的代碼時,以下最小工作示例進行編譯,但在使用選項3下的代碼時不編譯。 我假設emplace_back()
隱式使用/調用move
構造函數,那么為什么需要顯式move()
呢? 它與r-value
和l-value
嗎? 或者這與std::unique_ptr
需要轉移所有權有關嗎? (我仍然對這些概念不熟悉,特別是在這種情況下。)
為了完整性,除非調用move()
,否則帶有push_back()
選項4也不會編譯。
#include <iostream>
#include <vector>
#include <memory>
class Beta {
public:
Beta(int x, int y, int z): mX(x), mY(y), mZ(z) { };
int mX; int mY; int mZ;
};
class Alpha {
public:
std::vector<std::unique_ptr<Beta>> betaVec;
void addBeta(int x, int y, int z) {
// only choose one of the following options:
// option 1 (compiles)
std::unique_ptr<Beta> pBeta = std::make_unique<Beta>(x, y, z);
betaVec.emplace_back(move(pBeta));
// option 2 (compiles)
betaVec.emplace_back(std::make_unique<Beta>(x, y, z));
// option 3 (does not compile)
std::unique_ptr<Beta> pBeta = std::make_unique<Beta>(x, y, z);
betaVec.emplace_back(pBeta);
// option 4 (does not compile)
std::unique_ptr<Beta> pBeta = std::make_unique<Beta>(x, y, z);
betaVec.push_back(pBeta);
// option 5 (compiles)
std::unique_ptr<Beta> pBeta = std::make_unique<Beta>(x, y, z);
betaVec.push_back(move(pBeta));
}
};
int main() {
return 0;
}
注意:我不認為這是關於將unique_ptr
參數傳遞給函數的這個問題的重復,即使鏈接問題的答案很有用,因為這要求在函數中定義unique_ptr
然后將其移動到成員vector
以便它不會在函數結束時被銷毀,而且,在此上下文中具體詢問emplace_back()
。
另外,我認為在這種情況下給出解釋是有用的,因為有時很難將解釋從一個上下文轉換到另一個上下文。 謝謝!
我假設
emplace_back()
隱式使用/調用移動構造函數
對不起,但你的假設是錯的。 emplace_back
構造了向量中的對象,即不是從對象中復制/移動對象,而是直接構造元素,避免了復制/移動構造函數。
現在,如果您使用相同(但另一個)對象構造對象,那么當然要使用復制或移動構造函數,這就是您的情況。
那么為什么需要一個明確的
move()
因為你無法復制std::unique_ptr
。 基本上, emplace_back
做了類似於此的事情:
new (place) T(std::forward<Ts>(args)...);
就像你做的那樣: T a(std::forward<Ts>(args)...)
(僅用於構造,它實際上並沒有做同樣的事情)。
現在它可能更明顯一點:
T option1(std::move(pBeta)); // ok, move
T option3(pBeta); // error, copy
它與
r-value
和l-value
嗎? 或者這與std::unique_ptr
需要轉移所有權有關嗎?
那么,在某種程度上,是的。 std::unique_ptr
需要明確的所有權轉移,這就是為什么副本被禁用而移動不是(你仍然希望轉移所有權!並且副本可以在任何地方發生 - 為什么std::auto_ptr
被棄用,然后被刪除)。 右值默認使用移動語義,而左值則不使用移動語義。 通過使用std::move
,您正在進行從左值到初值的轉換,有效地“隱藏”您擁有左值的事實,編譯器將很樂意從它移動。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.