看看std :: remove参考我看到:
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
通过移动(通过移动分配)范围中的元素来完成移除 . 指向新逻辑结束和范围物理结束之间的元素的迭代器仍然是可解除引用的(根据MoveAssignable后置条件) .
所以,我看到MoveAssignable conept:
t = rv // Post-condition:The new value of rv is unspecified.
到目前为止,没关系 . 关于MoveAssignable概念的问题:
std::string s1 = "abc";
std::string s2;
s2 = std::move(s1);
std::cout << s1; // is this code valid?
s1 = "cde"; // is this code valid?
我可以通过读取其值或重新赋值来重用“移动自”变量吗?
现在我正在查看std :: move参考,它看起来有点令人惊讶:
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last, OutputIt d_first );
将[first,last]范围内的元素移动到从d_first开始的另一个范围 . After this operation the elements in the moved-from range will still contain valid values of the appropriate type ,但不一定与移动前的值相同 .
因此,move-from元素在std :: remove和std :: move中以不同的方式定义,尽管它们应该是相同的 . 哪一个是正确的?重新使用(或不使用)移动元素的规则是什么?
1 回答
标准中的实际措辞可在[lib.types.movedfrom]部分找到:
std::move
([alg.move])的描述简单地说,元素被移动并且不对移动的对象做出任何评论 .std::remove
([alg.remove])的描述有一个非规范性的说明:因此,cppreference恰好在这两个页面上使用不同的措辞,但它们的含义完全相同 .
现在,鉴于
std::string s1
已被移除,是否有效是的,这是允许的,因为
s1
是"valid",但它没用,因为你无法保证输出的内容 . 另一方面,既安全又有用,因为
s1
的任何先前内容都被丢弃了 .有关"unless otherwise specified"的示例,请查看
std::unique_ptr<T>
([unique.ptr.single.asgn])的移动赋值运算符:由于
u.release()
离开u
empty / null,我们实际上保证move-from对象将为空/ null . 类似的保证是针对移动构造函数和模板化构造函数以及使用不同模板参数的unique_ptr
赋值,因此移动的unique_ptr
始终为空/空 .