[英]What happens when constructor throws on vector.emplace or vector.emplace_back?
[英]why does vector.emplace_back call the move-constructor?
struct Object {
Object() { cout << "constructor\n"; }
Object(const Object &) { cout << "copy constructor\n"; }
Object(Object &&) { cout << "move constructor\n"; }
};
int main() {
vector<Object> v;
v.reserve(10);
v.emplace_back(Object{});
}
這給了我以下輸出:
建設者
移動構造函數
為什么? 我認為emplace_back確實會在原處創建Object,因此無需調用任何復制或移動構造函數。
根據描述:
元素是就地構造的,即不執行復制或移動操作。
編輯:啊,好的,看來我從根本上誤解了emplace_back()。 您不必將Object作為參數,因為它是為您自動創建的。 您只需將Object-constructor的參數提供給emplace_back()。
因此,如果我有一個像這樣的新構造函數:
Object(int) { cout << "int constructor\n"; }
我會這樣稱呼emplace_back:
v.emplace_back(42);
代替這個:
v.emplace_back(Object(42));
現在有意義,非常感謝!
EDIT2:希望我能接受您的所有答復! :-P
emplace_back
轉發它的參數向量元素類的構造函數,稱為就地上的下一個可用的位置vector
。
v.emplace_back(Object{});
相當於:
{
Object tmp;
v.emplace_back(std::move(tmp));
}
這就是為什么要得到常規構造函數調用以及移動構造函數調用的原因。 如果要使用emplace_back
附加新對象,只需調用:
v.emplace_back();
僅出於完整性考慮, emplace_back
可能調用move構造函數的另一個原因是: emplace_back
可能導致vector
增長,從而將其初始內容移動到其新的內存位置。 這不是這里的問題,因為調用reserve
保證足夠的容量,但這通常是問題的答案。
v.emplace_back(Object{});
將調用一個新的placement new new (place) Object(Object{})
因此移動構造函數。
使用v.emplace_back();
為了避免調用額外的對象構造函數,
這將導致new (place) Object;
emplace_back
調用與您傳遞的參數匹配的任何構造函數。 在這種情況下,您選擇傳遞與Object&&
move構造函數匹配的Object&&
Object{}
。
當描述說“不執行移動或復制”時,表示除指定的對象構造以外。 如果該構造恰好是移動或復制,那么當然可以執行。
如果希望emplace_back
使用no-args構造函數,則不傳遞任何參數: v.emplace_back()
。
您鏈接的版本用於傳遞構造函數參數。 為了達到預期的效果,可以調用v.emplace_back();
您正在emplace_back
與向量中存儲的相同類型的對象調用emplace_back
,因此您請求該對象的副本(與Object O(Object{});
)。 由於提供的是臨時文件,因此將調用move構造函數而不是copy構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.