讓我們來辦理手續。在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
。
'std :: move(v)'不會對'v'做任何事情。 'std :: move(v).pop_back();'與'v.pop_back();'有相同的效果(儘管這不能泛化到所有類型)。您發佈的報價缺少一些上下文。 – juanchopanza
@juanchopanza我的上下文來自[this](https://stackoverflow.com/questions/37262329/member-function-begin-and-stdbegin)。如果基礎範圍不再存在,那麼像「'begin」這樣的註釋並不是非常有用,所以它似乎沒有用處,因爲它有一個右值過載。「和「理論上,標準容器在rvalue上下文中沒有適當的用std :: begin來調用。與std :: move或rvalues交互的」正確「方式是你不'在呼叫完成後,應該關心移動目標的狀態。「似乎表明我錯過了一些東西。 –
@juanchopanza換句話說,'std :: begin(std :: move(x))'或'std :: move(x).begin()'與'std :: begin(x)'相同或'x.begin()'對嗎?那麼邏輯來自哪裏? –