2016-05-17 79 views
2

讓我們來辦理手續。在std :: move(x)上執行一些操作

28年3月17日有效,但非指定狀態[defns.valid]

,並非只是對象的 不變量表現爲指定 其類型

滿足和操作在對象上被指定的對象狀態

[示例:如果對象std::vector<int>類型的x處於有效但非指定狀態 ,x.empty()可以稱爲 無條件,和0123只有在x.empty()返回 false時纔可以調用。 - 端示例]

某些用戶已經建議std::move(x).something()是無意義的。但我無法理解std::move(x).something()y = std::move(x); y.something()之間的差異。注意:

// -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC 
std::vector<int> v; 
v.pop_back(); 
// Error: attempt to access an element in an empty container. 

現在,我們想試試我們的荒謬情況:

std::vector<int> v(10); 
std::move(v).pop_back(); 

沒有錯誤。這一定是每個人都在談論的「有效但不確定」,但我們繼續前進。

std::vector<int> v(10); 
std::cout << std::move(v).size(); 
auto v2 = std::move(v); 
std::cout << v.size(); 

這打印100。這並不令人感到意外。 std::move只是一個強制轉換,它並不實際執行移動構造函數的工作。

我錯過了什麼,或者是std::move(x).something()仍然是非感性的(除非是沒有操作)?


僅供參考,請參閱Member function .begin() and std::begin()的評論以及upvoted的答案。

下面的例子表明,v不從移動:

template< class C > 
auto begin(C&& c) -> decltype(c.begin()) 
{ 
    return c.begin(); 
} 

int main() 
{ 
    std::vector<int> v(10); 
    std::vector<int>::iterator it3 = begin(std::move(v)); 
    std::cout << v.size(); 
} 

輸出10

+3

'std :: move(v)'不會對'v'做任何事情。 'std :: move(v).pop_back();'與'v.pop_back();'有相同的效果(儘管這不能泛化到所有類型)。您發佈的報價缺少一些上下文。 – juanchopanza

+0

@juanchopanza我的上下文來自[this](https://stackoverflow.com/questions/37262329/member-function-begin-and-stdbegin)。如果基礎範圍不再存在,那麼像「'begin」這樣的註釋並不是非常有用,所以它似乎沒有用處,因爲它有一個右值過載。「和「理論上,標準容器在rvalue上下文中沒有適當的用std :: begin來調用。與std :: move或rvalues交互的」正確「方式是你不'在呼叫完成後,應該關心移動目標的狀態。「似乎表明我錯過了一些東西。 –

+0

@juanchopanza換句話說,'std :: begin(std :: move(x))'或'std :: move(x).begin()'與'std :: begin(x)'相同或'x.begin()'對嗎?那麼邏輯來自哪裏? –

回答

6

std::move不對對象做任何事情!它所做的就是對象賦值給一個ravlue,以便它可以被右值引用綁定。

對象的任何修改都由相應的移動構造函數或移動賦值操作符完成。如果沒有人被調用,則什麼都不會發生。

+0

s /轉換/轉換 – Barry

+0

@Barry同意,將會修復。 – SergeyA

0

但我無法理解std::move(x).something()y = std::move(x); y.something()

之間,(const&/&&注)的區別

struct S 
{ 
    void foo() const & {std::cout << "l-value this\n"; } 
    void foo() const && {std::cout << "r-value this\n"; } 
}; 

你得到了:

S tmp; 
std::move(tmp).foo(); // "r-value this 

S x = std::move(tmp); 
x.foo(); // "l-value this 
相關問題