让我们来办理手续。在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()'对吗?那么逻辑来自哪里? –