让我们办理手续。
17.3.28有效但未指明的状态[defns.valid]
除了对象之外没有指定的对象状态 满足不变量,对象上的操作按指定行为 对于它的类型
[示例:如果
x
类型的对象std::vector<int>
是 在有效但未指定的状态下,可以调用x.empty()
无条件地,只有x.front()
返回时才能调用x.empty()
假。 - 结束示例]
有些用户建议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()上的评论以及推荐的答案。
以下示例表明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
。
答案 0 :(得分:6)
std::move
对该对象没有任何作用!它只是将一个对象转换为ravlue,因此它可以被右值引用绑定。
对象的任何修改都由相应的移动构造函数或移动assingnment操作符完成。如果没有人被调用,根本没有任何事情发生。
答案 1 :(得分: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