2016-05-17 68 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