2013-05-19 55 views
3

我想用std::vector::push_back()將對象轉換爲std::vector。這似乎是可能的,因爲有一個std::vector::push_back(value_type&& val)函數。但由於std::vector::push_back(value_type const & val)的存在,它會複製並重載調用,所以我需要將左值對象轉換爲右值。你如何將左值轉換爲右值?那麼新「左值」會發生什麼?

這是如何完成的?

例子:

struct X { int x; X(int x) : x(x) {} }; 

int main() 
{ 
    std::vector<X> ax; 
    X x(3); 
    ax.push_back(x); // <= Want to move x in to vector ax, not copy. 
    return 0; 
} 

其實,也許就不能?我問這個,因爲寫這個例子後,我的新問題是:

  • 如果我不動xax,什麼是x.x價值?如果X有一個明確的析構函數,當它離開作用域時x會發生什麼?

回答

4

只需使用std::move()

ax.push_back(std::move(x)); 

關於你的問題:

如果我做移動X成斧,什麼是x.x中的價值?

在這種情況下,您的X類不包含顯式聲明的移動構造函數,所以編譯器會生成一個不按成員X的成員的舉動。由於X只有int類型的一個成員,並且移動int與複製它沒有區別,那麼x.x將具有與移動之前相同的值。

如果X有一個顯式的析構函數,那麼當它離開作用域時x會發生什麼?

如果X有一個用戶聲明析構函數,這將抑制隱式轉移構造函數的生成 - 但不是一個隱含的拷貝構造函數。因此,此函數調用:

ax.push_back(std::move(x)); 

會導致x複製ax。在任何情況下,x在超出範圍時都會被銷燬,因爲它具有自動存儲持續時間 - 無論是否存在用戶聲明的析構函數。

一般而言,除了該狀態有效外,不應對已移出的對象的狀態做出假設(C++ 11 Standard的第17.6.5.15/1節保證這種情況是這種情況對於標準庫的類型)。

具體而言,這意味着唯一可以安全地使用已經移動的對象的函數是那些對該對象的狀態沒有任何先決條件的函數。通常,兩個這樣的函數是析構函數和(複製或移動)賦值運算符。

+0

哦,就這麼簡單吧?最後我的另外兩個問題呢? – Adrian

+0

如果它有明確的一個?雖然我寫了一個簡單的例子,但我希望有一個完整的理解,並且爲什麼我規定'如果X有一個明確的析構函數......' – Adrian

+0

@Adrian:我編輯了覆蓋該問題的答案 –

相關問題