[英]Return std::tuple and move semantics / copy elision
我有以下工廠功能:
auto factory() -> std::tuple<bool, std::vector<int>>
{
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
return { true, vec };
}
auto [b, vec] = factory();
在 return 語句中vec
被視為xvalue
或prvalue
並因此被移動或復制省略?
我的猜測是否定的,因為編譯器在 return 語句中列表初始化std::tuple
時,仍然不知道 vec 將被銷毀。 所以也許需要一個顯式的 std::move :
auto factory() -> std::tuple<bool, std::vector<int>>
{
...
return { true, std::move(vec) };
}
auto [b, vec] = factory();
真的有這個要求嗎?
在 return 語句中
vec
被視為 xvalue 或 prvalue 並因此被移動或復制省略?
vec
始終是左值。 即使在簡單的情況下:
std::vector<int> factory() {
std::vector<int> vec;
return vec;
}
那仍然是返回一個左值。 只是我們有特殊的規則,在這種情況下,當我們返回一個自動對象的名稱時,我們只是忽略副本(還有另一個特殊規則,在復制省略不適用的情況下,但我們仍然嘗試從左值移動)。
但那些特殊規則只適用於return object;
情況下,它們不適用於return {1, object};
情況,無論它看起來多么相似。 在您的代碼中,這將進行復制,因為這是您所要求的。 如果你想做一個動作,你必須這樣做:
return {1, std::move(object)};
為了避免移動,你必須這樣做:
auto factory() -> std::tuple<bool, std::vector<int>>
{
std::tuple<bool, std::vector<int>> t;
auto& [b, vec] = t;
b = true;
vec.push_back(1);
vec.push_back(2);
return t;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.